访问者模式
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
Element抽象元素一般是抽象类或者接口,它定义一个accept()方法,该方法通常以一个抽象访问者作为参数。使用的是“双重分派”机制,使得增加新的访问者无须修改现有类库代码,只需将新的访问者对象作为参数传入具体元素对象的accept()方法。
ObjectStructure对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。
使用访问者模式要求Element的对象结构稳定,比如后期人、突然要添加一个ElementC,这样就要去修改Visitor相关类的源码,不符合开闭原则。
public interface Element {
void accept(Visitor visitor);
}
public class ElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public class ElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public abstract class Visitor {
public abstract void visit(ElementA elementA);
public abstract void visit(ElementB elementB);
}
public class VisitorA extends Visitor {
@Override
public void visit(ElementA elementA) {
System.out.println(this + "关于" + elementA + "的相关操作");
}
@Override
public void visit(ElementB elementB) {
System.out.println(this + "关于" + elementB + "的相关操作");
}
}
public class ObjectStructure {
private List<Element> elementList;
public ObjectStructure() {
this.elementList = new ArrayList<>();
}
public void addElement(Element element) {
elementList.add(element);
}
public void removeElement(Element element) {
elementList.remove(element);
}
public void accept(Visitor visitor) {
elementList.forEach(element -> element.accept(visitor));
}
}
@Test
public void VisitorTest() {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.addElement(new ElementA());
objectStructure.addElement(new ElementB());
objectStructure.accept(new VisitorA());
}