访问者模式
访问者模式:表示一个作用域某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义操作用于这些元素的新操作。
UML图:
1 //Element类,定义一个Accept操作,它以一个访问者为参数 2 public abstract class Element { 3 public abstract void accept(Visitor visitor); 4 }
1 //ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作。 2 public class ConcreteElementA extends Element { 3 4 //充分利用双分派技术,实现处理与数据结构的分离 5 @Override 6 public void accept(Visitor visitor) { 7 // TODO Auto-generated method stub 8 visitor.visitConcreteElementA(this); 9 } 10 11 //其它的相关方法 12 public void operatorA(){ 13 14 } 15 16 }
1 //ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作。 2 public class ConcreteElementB extends Element { 3 4 //充分利用双分派技术,实现处理与数据结构的分离 5 @Override 6 public void accept(Visitor visitor) { 7 // TODO Auto-generated method stub 8 visitor.visitConcreteElementB(this); 9 } 10 11 //其它的相关方法 12 public void operatorB(){ 13 14 } 15 16 }
1 //Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作 2 public abstract class Visitor { 3 public abstract void visitConcreteElementA(ConcreteElementA concreteElementA); 4 public abstract void visitConcreteElementB(ConcreteElementB concreteElementB); 5 }
1 /** 2 * ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。 3 * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。 4 * @author 贤元 5 * 6 */ 7 public class ConcreteVisitor1 extends Visitor { 8 9 @Override 10 public void visitConcreteElementA(ConcreteElementA concreteElementA) { 11 System.out.println(concreteElementA.getClass().getTypeName()+"被"+this.getClass().getTypeName()+"访问"); 12 13 } 14 15 @Override 16 public void visitConcreteElementB(ConcreteElementB concreteElementB) { 17 System.out.println(concreteElementB.getClass().getTypeName()+"被"+this.getClass().getTypeName()+"访问"); 18 } 19 20 }
1 /** 2 * ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。 3 * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。 4 * @author 贤元 5 * 6 */ 7 public class ConcreteVisitor2 extends Visitor { 8 9 @Override 10 public void visitConcreteElementA(ConcreteElementA concreteElementA) { 11 System.out.println(concreteElementA.getClass().getTypeName()+"被"+this.getClass().getTypeName()+"访问"); 12 13 } 14 15 @Override 16 public void visitConcreteElementB(ConcreteElementB concreteElementB) { 17 System.out.println(concreteElementB.getClass().getTypeName()+"被"+this.getClass().getTypeName()+"访问"); 18 } 19 20 }
1 //ObjectStructure类,能枚举他的元素,可以提供一个高层的接口以允许访问者访问它的元素 2 public class ObjectStructure { 3 private List<Element> elemenets = new ArrayList<Element>(); 4 public void attach(Element element){ 5 elemenets.add(element); 6 } 7 public void detach(Element element){ 8 elemenets.remove(element); 9 } 10 public void accept(Visitor visitor){ 11 for(Element e:elemenets){ 12 e.accept(visitor); 13 } 14 } 15 }
//客户端代码 public class TestClient { 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); /** * 打印结果: org.lixianyuan.visitor.ConcreteElementA被org.lixianyuan.visitor.ConcreteVisitor1访问 org.lixianyuan.visitor.ConcreteElementB被org.lixianyuan.visitor.ConcreteVisitor1访问 org.lixianyuan.visitor.ConcreteElementA被org.lixianyuan.visitor.ConcreteVisitor2访问 org.lixianyuan.visitor.ConcreteElementB被org.lixianyuan.visitor.ConcreteVisitor2访问 */ } }
不能只满足于写完代码运行结果正确就完事,时常考虑如何让代码更加简练更加容易维护、容易扩展和复用,只有这样才可以真正得到提高
--《来自大话设计模式》