Loading... # 设计模式(二十五)——访问者模式 ## 参考 > 大话设计模式  ——  程杰 著 ## 目录 [设计模式(一)——简单工厂模式](https://www.princelei.club/archives/67.html) [设计模式(二)——策略模式](https://www.princelei.club/archives/68.html) [设计模式(三)——设计原则](https://www.princelei.club/archives/116.html) [设计模式(四)——装饰模式](https://www.princelei.club/archives/117.html) [设计模式(五)——代理模式](https://www.princelei.club/archives/119.html) [设计模式(六)——工厂方法模式](https://www.princelei.club/archives/132.html) [设计模式(七)——原型模式](https://www.princelei.club/archives/133.html) [设计模式(八)——模板方法模式](https://www.princelei.club/archives/134.html) [设计模式(九)——外观模式](https://www.princelei.club/archives/135.html) [设计模式(十)——建造者模式](https://www.princelei.club/archives/136.html) [设计模式(十一)——观察者模式](https://www.princelei.club/archives/137.html) [设计模式(十二)——抽象工厂模式](https://www.princelei.club/archives/138.html) [设计模式(十三)——状态模式](https://www.princelei.club/archives/139.html) [设计模式(十四)——适配器模式](https://www.princelei.club/archives/140.html) [设计模式(十五)——备忘录模式](https://www.princelei.club/archives/141.html) [设计模式(十六)——组合模式](https://www.princelei.club/archives/147.html) [设计模式(十七)——迭代器模式](https://www.princelei.club/archives/148.html) [设计模式(十八)——单例模式](https://www.princelei.club/archives/157.html) [设计模式(十九)——桥接模式](https://www.princelei.club/archives/159.html) [设计模式(二十)——命令模式](https://www.princelei.club/archives/160.html) [设计模式(二十一)——职责链模式](https://www.princelei.club/archives/161.html) [设计模式(二十二)——中介者模式](https://www.princelei.club/archives/162.html) [设计模式(二十三)——享元模式](https://www.princelei.club/archives/163.html) [设计模式(二十四)——解释器模式](https://www.princelei.club/archives/173.html) [设计模式(二十五)——访问者模式](https://www.princelei.club/archives/174.html) ## 何为访问者模式 - 访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 ## 示例 Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作。 ``` /** * Visitor类 */ public interface Visitor { void visitConcreteElementA(ConcreteElementA concreteElementA); void visitConcreteElementB(ConcreteElementB concreteElementB); } ``` ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。 ``` /** * ConcreteVisitor1 */ public class ConcreteVisitor1 implements Visitor { @Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println(concreteElementA + "被" + this + "访问"); } @Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println(concreteElementB + "被" + this + "访问"); } } ``` ``` /** * ConcreteVisitor2 */ public class ConcreteVisitor2 implements Visitor{ @Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println(concreteElementA + "被" + this + "访问"); } @Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println(concreteElementB + "被" + this + "访问"); } } ``` Element类,定义一个accept操作,它以一个访问者为参数。 ``` /** * Element类 */ public interface Element { void accept(Visitor visitor); } ``` ConcreteElementA和ConcreteElementB类,具体元素,实现accept操作。 ``` /** * ConcreteElementA */ public class ConcreteElementA implements Element{ @Override public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); } } ``` ``` /** * ConcreteElementB */ public class ConcreteElementB implements Element{ @Override public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); } } ``` ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。 ``` /** * ObjectStructure */ public class ObjectStructure { private List<Element> elements = new ArrayList<>(); public void attach(Element element) { elements.add(element); } public void detach(Element element) { elements.remove(element); } public void accept(Visitor visitor) { elements.forEach(e -> { e.accept(visitor); }); } } ``` 客户端 ``` /** * 客户端 */ public class MainClass { public static void main(String[] args) { ObjectStructure o = new ObjectStructure(); o.attach(new ConcreteElementA()); o.attach(new ConcreteElementB()); ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2(); o.accept(v1); o.accept(v2); } } ``` ## 何时使用访问者模式   访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解开,使得操作集合可以相对自由地演化。访问者模式的目的是要把处理从数据结构分离出来,如果系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式是比较合适的,因为访问者模式使得算法操作的增加变得容易。   大多时候你并不需要访问者模式,但当一旦你需要访问者模式时,那就是真的需要它了。事实上,我们很难找到数据结构不变化的情况,所以用访问者模式的机会也就不太多。访问者模式的能力和复杂性是把双刃剑,只有当你真正需要它的时候,才考虑使用它。有很多程序员为了展示自己的面向对象的能力或是沉迷于模式中,往往会误用这个模式,不过我估计大多数人不去用它的原因绝对不是因为怕误用,而是因为它太过于复杂和晦涩,根本不能理解,不熟悉的东西当然就不会想着去应用它。 ## 优点 1. 增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。 2. 访问者模式将有关的行为集中到一个访问者对象中。 ## 缺点 - 使增加新的数据结构变得困难了。 Last modification:June 11th, 2020 at 06:19 pm © 允许规范转载