访问者模式
定义
Represent an operation to be performed on the elements of an objects structure.Vistor lets you define a new operation without changing the classes of the elements on which it operates.
封装一些作用于某种数据结构中的各元素操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
访问者模式示意图
流程
客户获取需要的信息,首先需要让对象结构生产出元素对象。
元素先接受访问者的访问,访问者就可以获取生产的元素对象。
访问者就可以按自己的方式操作元素对象,获得客户端需要的信息。
最终客户端能够得到需要的信息。
代码实现
元素
创建所有元素的抽象类
1 2 3 4 5 6 7 8 9 public abstract class Element { public abstract void test () ; public abstract void accept (IVisitor visitor) ; }
创建继承抽象类的具体元素1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class ConcreteElement1 extends Element { @Override public void test () { System.out.println("元素1" ); } @Override public void accept (IVisitor visitor) { visitor.visit(this ); } }
创建继承抽象类的具体元素2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class ConcreteElement2 extends Element { @Override public void test () { System.out.println("元素2" ); } @Override public void accept (IVisitor visitor) { visitor.visit(this ); } }
访问者
创建所有访问者需要实现的接口
1 2 3 4 5 6 7 8 9 public interface IVisitor { public void visit (ConcreteElement1 element1) ; public void visit (ConcreteElement2 element2) ; }
创建访问者,这个访问者能够访问元素1和元素2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ConcreteVisitor implements IVisitor { @Override public void visit (ConcreteElement1 element1) { element1.test(); } @Override public void visit (ConcreteElement2 element2) { element2.test(); } }
对象结构
创建一个用来生产元素对象的对象结构
1 2 3 4 5 6 7 8 9 10 11 12 13 public class ObjectStructure { public static Element createElement () { Random random = new Random(); if (random.nextInt(100 ) > 50 ) { return new ConcreteElement1(); }else { return new ConcreteElement2(); } } }
场景实现
1 2 3 4 5 6 7 8 9 10 11 public class Test { public static void main (String[] args) { for (int i=0 ; i<10 ; i++){ Element element = ObjectStructure.createElement(); element.accept(new ConcreteVisitor()); } } }
应用场景
一个对象结构有很多不同接口的对象,我们需要对这些对象实施依赖具体类的操作。
需要对一个对象结构中的对象进行很多不同且不相关的操作。
访问者模式使迭代器模式的扩展,当迭代器不能胜任,我们能使用访问者模式。
访问者模式的优点和缺点
优点
符合单一职责原则,元素只负责加载数据,访问者只负责展现数据,对象结构只负责创建对象。
扩展性非常好。对数据的操作很快捷,如果要增加操作,只需要在访问者中增加对应方法就行了。
非常好的灵活性。
缺点
具体元素对访问者公开,违反迪米特原则。
具体元素变更很困难。
访问者直接访问具体元素,违反了依赖倒置原则。