Visitor(访问者)
程序员文章站
2023-12-22 23:09:16
...
Visitor(访问者) 行为型对象1
Intent_意图2
封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变
Motivation_动机3
解决稳定的数据结构和易变的操作耦合问题
Applicability_适用性4
当想要为一个对象的组合增加新的能力,且封装并不重要时,使用访问者模式
Structure_结构5
Participants_参与者6
- Visitor(抽象访问者) 声明了一个或多个方法操作,形成所有ConcreteVisitor必须实现的接口
- ConcreteVisitor(具体访问者) 实现Visitor所声明的接口,也就是Visitor所声明的各个访问操作
- Element(抽象元素) 声明一个接受操作,接受一个Visitor作为一个参数
- ConcreteElement(具体元素) 实现了Element所规定的接受操作
- ObjectStructure(结构对象) 可以遍历结构中的所有Element;如果需要,提供一个记层的接口让Visitor对象可以访问每一个Element;如果需要,可以设计成一个复合对象或一个聚集,如List或Set
Collaborations_协作7
- Client创建一个ObjectStructure,然后将新的ConcreteElement对象传入
- Client创建ConcreteVisitor对象,并将此对象传给ObjectStructure对象
- Client调用ObjectStructure对象聚集管理方法,将ConcreteElement加入到ObjectStructure对象中去
- Client调用ObjectStructure对象的行动方法action(),启动访问过程
- ConcreteElement对象接到方法accept()被调用,并将ConcreteVisitor对象本身传入
- ConcreteElement对象反过来调用ConcreteVisitor对象的访问方法,并将ConcreteElement对象本身传入
- ConcreteVisitor对象调用ConcreteElement对象的特有方法operation()
Comsequences_结果8
- 优点
优秀的扩展性,能在不改变对象本身结构中元素的情况下,为对象结构中的元素添加新的功能
优秀的复用性,元素类可以通过接受不同的访问者来实现不同的操作的复用
符合单一职责原则,访问者和被访问者独立分开,各自负责各自的职责 - 缺点
对象结构变化困难,当对象结构发生了改变,访问者的接口和访问者的实现都要发生相应的改变
破坏封装,元素需要开放内部数据给访问者和结构对象 - 用途
结构对象中对象对应的类很少改变,但经常需要在此对象上定义新的操作
需要对一个对结构对象中的对象进行很多不同的且不相关的操作
Implementation/Sample Code_实现/范例代码910
Implementation
Visitor
public interface Visitor {
public void visit(ConcreteElementA element);
public void visit(ConcreteElementB element);
}
ConcreteVisitor
public class ConcreteVisitorA implements Visitor {
@Override
public void visit(ConcreteElementA element) {
element.operationA();
}
@Override
public void visit(ConcreteElementB element) {
element.operationB();
}
}
public class ConcreteVisitorB implements Visitor {
@Override
public void visit(ConcreteElementA element) {
element.operationA();
}
@Override
public void visit(ConcreteElementB element) {
element.operationB();
}
}
Element
public interface Element {
public void accept(Visitor visitor);
}
ConcreteElement
public class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationA() {
System.out.println("Concrete Element A");
}
}
public class ConcreteElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public void operationB() {
System.out.println("Concrete Element B");
}
}
ObjectStructure
public class ObjectStructure {
private List<Element> elements = new ArrayList<Element>();
public void action(Visitor visitor) {
for (Element element : elements) {
element.accept(visitor);
}
}
public void add(Element element) {
elements.add(element);
}
}
Client
public class Client {
public static void main(String[] args) {
ObjectStructure cs = new ObjectStructure();
cs.add(new ConcreteElementA());
cs.add(new ConcreteElementB());
Visitor visitor = new ConcreteVisitorA();
cs.action(visitor);;
}
}
Sample Code
Known Uses_已知应用11
Related Patterns_相关模式12
-
模式分类归属 ↩︎
-
意图:描述该模式的作用,以及该模式的定义 ↩︎
-
动机:给出了问题以及如何解决这个问题的具体场景 ↩︎
-
适用性:描述模式可以被应用在什么场合 ↩︎
-
结构:提供了图示,显示出参与此模式的类之间的关系 ↩︎
-
参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色 ↩︎
-
协作 :告诉参与者如何在此模式中合作 ↩︎
-
结果:描述采用此模式之后可能产生的效果,好的与不好的 ↩︎
-
实现:提供了在实现该模式时需要使用的技巧,以及应该小心面对的问题 ↩︎
-
范例代码:提供代码的片段 ↩︎
-
已知应用:用来描述已经在真实系统中发现的模式例子 ↩︎
-
相关模式:描述了此模式和其他模式之间的关系 ↩︎