访问者模式:
修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法。ConcreteElementA和ConcreteElementB 就是原有的类,现在需要给ConcreteElementA增加一个方法
visitElementA给ConcreteElementB增加一个方法 visitElementB,接口Visitor定义了这两个方法,那么怎么让新增的方法被调用呢?于是出现了Visitor的实现类,
当然被访问了两个类也有个新名字的方法叫accept,并抽象为接口,这个入参是关键,因为这里恰好是衔接的地方,
入参是访问者接口,这也就是把访问者的方法暴漏给了被访问的两个类,呵呵,作用可想而知了:
package com.jerry.design.visitor; import java.util.ArrayList; import java.util.Collection; interface Visitor{ public void visitElementA(ConcreteElementA elementA);//针对具体元素A的新方法 public void visitElementB(ConcreteElementB elementB);//针对具体元素B的新方法 } interface Element{ public void accept(Visitor visitor); } class ConcreteVisitor implements Visitor{//具体的访问者 public void visitElementA(ConcreteElementA elementA) { System.out.println(elementA.getName()+" visited by ConcreteVisitor "); } public void visitElementB(ConcreteElementB elementB) { System.out.println(elementB.getName()+" visited by ConcreteVisitor "); } } class ConcreteElementA implements Element{//具体元素A private String name; public ConcreteElementA(String name){ this.name=name; } public void accept(Visitor visitor) {//接受访问者调用它针对该元素的新方法 visitor.visitElementA(this); } public String getName() { return name; } } class ConcreteElementB implements Element{//具体元素B private String name; public ConcreteElementB(String name){ this.name=name; } public String getName() { return name; } public void accept(Visitor visitor) {//接受访问者调用它针对该元素的新方法 visitor.visitElementB(this); } } class ObjectStructure{//对象结构即元素的集合 private Collection<Element> collection=new ArrayList<Element>(); public void attach(Element element){ collection.add(element); } public void detach(Element element){ collection.remove(element); } public void accept(Visitor visitor ) { for(Element element:collection){ element.accept(visitor); } } } public class Test { public static void main(String args[]){ Element elementA=new ConcreteElementA("ElementA"); Element elementB=new ConcreteElementB("ElementB"); Visitor visitor=new ConcreteVisitor(); ObjectStructure os=new ObjectStructure(); os.attach(elementA); os.attach(elementB); os.accept(visitor); } }