行为型模式涉及怎样合理的设计对象之间的交互通信,以及怎样合理为对象分配职责,让设计富有弹性,易维护,易复用
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
策略模式
定义:定义了算法家族,并将每一个算法封装起来,而且使它们还可以相互替换。(让算法变化不会影响使用算法的用户)
适用场景:系统有很多类,而他们的区别仅仅在于他们的行为不同。一个系统需要动态地在几种算法中选择一种。
优点:开闭原则,避免使用多重条件转移语句。提高算法的保密性和安全性。
缺点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
class StrategyC extends Strategy {
@Override
void algorithmInterface() {
System.out.println("算法C");
}
}
// 使用上下文维护算法策略
class Context {
Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void algorithmInterface() {
strategy.algorithmInterface();
}
}
//感觉这像代理模式的写法
class ClientTestStrategy {
public static void main(String[] args) {
Context context;
context = new Context(new StrategyA());
context.algorithmInterface();
context = new Context(new StrategyB());
context.algorithmInterface();
context = new Context(new StrategyC());
context.algorithmInterface();
}
}
//这里的实例化可以改成传入一个参数,,然后通过这个参数在spring中获取对应的对象方法
public static void main(String[] args) {
String promotionKey = "MANJIANxxx";
Context context;
context = new Context(SpringUtil.getBean(promotionKey));
}
模板方法模式
定义:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。(使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。)
适用场景:一次性定义算法的不变部分,将可变的行为留给子类来实现。子类中的公共行为被提取出来集中到一个公共父类中,从而避免大量重复代码。
优点:提高复用性、提高扩展性、符合开闭原则。
缺点:增加类的数目,增加了子系统实现的复杂度,如果父类添加新的抽象方法,所有子类都要修改。
比如一个棋牌麻将:父类有打牌、过牌、碰牌、胡牌方法接口,交给子类去实现。父类实现开始游戏玩家信息初始化、结算时金币扣除和日子存储!
//模板方法
public abstract class BankTemplateMethod {
// 1.取号排队
public void takeNumber() {
System.out.println("取号排队。。");
}
// 2.每个子类不同的业务实现,由各自子类实现.
abstract void transact();
// 3.评价
public void evaluate() {
System.out.println("反馈评价..");
}
public void process(){
takeNumber();
transact();
evaluate();
}
}
迭代器模式
定义:提供了一种方法,顺序访问一个集合对象中的各个元素,而又不暴露改对象的内部表示。
适用场景:为访问集合提供了一个统一的接口。访问一个集合的内容而无需暴露它的内部表示。
优点:分离了集合对象的遍历行为。
缺点:类的个数成对增加。
//定义抽象迭代器
public interface Iterator<T> {
T first(); //将游标指向第一个元素
T next(); //将游标指向下一个元素
boolean hasNext(); //判断是否存在下一个元素
T currentItem(); //获取游标指向的当前元素
}
//定义抽象聚合类
public interface Aggregate<T> {
void add(T t);
void remove(T t);
Iterator<T> createIterator();
}
//定义具体的聚合类
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> lists = new ArrayList<>();
@Override
public Iterator<T> createIterator() {
return new ConcreteIterator(lists);
}
@Override
public void add(T t) {
lists.add(t);
}
@Override
public void remove(T t) {
lists.remove(t);
}
}
//定义具体的迭代器类
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> lists;//维持一个对具体聚合对象的引用,以便于访问存储在聚合对象中的数据
private int cursor; //定义一个游标,用于记录当前访问位置
public ConcreteIterator(List<T> list) {
this.lists=list;
}
@Override
public T first() {
return lists.get(0);
}
@Override
public T next() {
T obj = null;
if (this.hasNext()) {
obj = this.lists.get(cursor++);
}
return obj;
}
@Override
public boolean hasNext() {
return false;
}
@Override
public T currentItem() {
return null;
}
}
解释器模式
定义:给定一个语言,定义它语法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。(为了解释一种语言,而为语言创建的解释器)
适用场景:某个特定类型问题发生频率足够高。
优点:语法由很多类表示,容易改变及扩展此“语言”。
缺点:当语法规则数目太多时,增加了系统复杂度。
6 100 11 + * 计算方式 符号由左向右获取,数字由右向左获取。(100 + 11)* 6
public static void main(String[] args) {
String geelyInputStr="6 100 11 + *";
GeelyExpressionParser expressionParser=new GeelyExpressionParser();
int result=expressionParser.parse(geelyInputStr);
System.out.println("解释器计算结果: "+result);
}
观察者模式
观察者模式主要用于1对N的通知。(一个望风的,班主任来了,好通知全班学生)
定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新。
适用场景:关联行为场景,建立一套触发机制。
优点:观察者和被观察者间建立一个抽象耦合,支持广播通讯。
缺点:观察者之间有过多的细节依赖、提高时间消耗及程序复杂度。要避免循环调用。
//观察者的接口,用来存放观察者共有方法
public interface Observer {
// 观察者方法
void update(Subjecct subjecct);
}
//观察对象的父类
public class Subjecct {
//观察者的存储集合
private List<Observer> list = new ArrayList<>();
// 注册观察者方法
public void registerObserver(Observer obs) {
list.add(obs);
}
// 删除观察者方法
public void removeObserver(Observer obs) {
list.remove(obs);
this.notifyAllObserver();
}
// 通知所有的观察者更新
public void notifyAllObserver() {
for (Observer observer : list) {
observer.update(this);
}
}
}
//具体观察者对象的实现
public class RealObserver extends Subjecct {
//被观察对象的属性
private int state;
public int getState(){
return state;
}
public void setState(int state){
this.state=state;
//主题对象(目标对象)值发生改变
this.notifyAllObserver();
}
}
public class Client {
public static void main(String[] args) {
// 目标对象
RealObserver subject = new RealObserver();
// 创建多个观察者
ObserverA obs1 = new ObserverA();
ObserverA obs2 = new ObserverA();
ObserverA obs3 = new ObserverA();
// 注册到观察队列中
subject.registerObserver(obs1);
subject.registerObserver(obs2);
subject.registerObserver(obs3);
// 改变State状态
subject.setState(300);
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
// 改变State状态
subject.setState(400);
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}