1.前言
- 设计模式共有23种(点击这里查看更多分类),根据目的准则分类,分为三类
- 创建型设计模式,共5种:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
- 结构型设计模式,共7中:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、响元模式。
- 行为设计模式,共11种:策略模式、模版方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
- 这里介绍一下访问者模式。
2.特点
- 定义:将数据结构和数据操作分离
2.1.代码说明
- 举例:用日记记录今天做了什么事情。
首先,定义接口类Execute,如下:
public interface Execute {
void doSomething(DailyVisitor visitor);
}
定义Execute的接口实现类,分别是:Game、Work、Shop,如下:
public class Game implements Execute {
@Override
public void doSomething(DailyVisitor visitor) {
visitor.recordVisitor(this);
}
}
public class Work implements Execute {
@Override
public void doSomething(DailyVisitor visitor) {
visitor.recordVisitor(this);
}
}
public class Shop implements Execute {
@Override
public void doSomething(DailyVisitor visitor) {
visitor.recordVisitor(this);
}
}
定义Today类,实现Execute,如下:
public class Today implements Execute {
private List<Execute> mExecuteList = new ArrayList<>();
public Today() {
mExecuteList.add(new Game());
mExecuteList.add(new Work());
mExecuteList.add(new Shop());
}
@Override
public void doSomething(DailyVisitor visitor) {
visitor.recordVisitor(this);
for (int i = 0; i < mExecuteList.size(); i++) {
mExecuteList.get(i).doSomething(visitor);
}
}
}
定义接口类DailyVisitor,如下:
public interface DailyVisitor {
void recordVisitor(Execute game);
void recordVisitor(Game game);
void recordVisitor(Work work);
void recordVisitor(Shop shop);
}
定义接口类DailyVisitor的实现类Daily,如下:
public class Daily implements DailyVisitor {
@Override
public void recordVisitor(Execute game) {
System.out.println("开始记录今天的日记:");
}
@Override
public void recordVisitor(Game game) {
System.out.println("上午打电脑游戏");
}
@Override
public void recordVisitor(Work work) {
System.out.println("下午工作");
}
@Override
public void recordVisitor(Shop shop) {
System.out.println("晚上逛商场");
}
}
最终调用,如下:
Execute execute = new Today();
execute.doSomething(new Daily());
//--------打印日志--------
System.out: 开始记录今天的日记:
System.out: 上午打电脑游戏
System.out: 下午工作
System.out: 晚上逛商场
2.2.优缺点
- 优点:扩展性良好(增加具体的事情只需要实现Execute接口类);各个类各负其责,符合单一职责的原则;代码的灵活性较好
- 缺点:实现Execute接口类的具体事情变更困难;违反了依赖倒置原则(高层模块不应该依赖底层模块,两者都应该依赖于抽象)
2.3.使用场景
- 对象结构比较稳定,但经常需要在此对象结构上定义新的操作(也就是可能会有多个Execute接口的实现类)。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
3.总结
有疑问可以留言!