访问者模式:
修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法。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);
}
}