# 访问者 (Visitor)
当想要为对象的组合增加新的能力且封装并不重要时,就可以使用访问者模式。
现在需要知道的就是,被访问的类需要将自身引用传入访问者。讲起来比较空泛,所以先看代码。
# 实现
代码来自菜鸟教程。
- 定义表示元素的接口:
public interface ComputerPart { | |
// 接口定义的行为:元素提供一个方法供访问者进入 | |
// 假设存在 ComputerPartVisitor 接口定义了访问者的 visit 行为 | |
public void accept(ComputerPartVisitor computerPartVisitor); | |
} |
- 创建扩展上述类的实体类
// 创建一个键盘实体类 | |
public class Keybord implements ComputerPart { | |
@Override | |
public void accept(ComputerPartVisitor computerPartVisitor) { | |
// 实体类实现的行为是:将自己的引用 this 暴露给外部访问者 | |
computerPartVisitor.visit(this); | |
} | |
} | |
// 创建一个监视器实体类 | |
public class Monitor implements ComputerPart { | |
@Override | |
publicvoid accept(ComputerPartVisitor computerPartVisitor) { | |
computerPartVisitor.visit(this); | |
} | |
} | |
// 创建一个鼠标实体类 | |
public class Mouse implements ComputerPart { | |
@Override | |
public void accept(ComputerPartVisitor computerPartVisitor) { | |
computerPartVisitor.visit(this); | |
} | |
} |
- 再写一个总体的类
public class Computer implements ComputerPart { | |
ComputerPart[] parts; | |
public Computer() { | |
parts = new ComputerPart[] { | |
new Mouse(),new Keyboard(),new Monitor() | |
}; | |
@Override | |
public void accept(ComputerPartVisitor computerPartVisitor) { | |
for(int i = 0;i < n;i++) { | |
parts[i].accept(computerPartVisitor); | |
} | |
computerPartVisitor.visit(this); | |
} | |
} | |
} |
- 创建一个实体访问者类
public class ComputerPartDisplayVisitor implements ComputerPartVisitor { | |
@Override | |
public void visit(Computer computer) { | |
System.out.println("Displaying Computer."); | |
} | |
@Override | |
public void visit(Mouse mouse) { | |
System.out.println("Displaying Mouse."); | |
} | |
@Override | |
public void visit(Keyboard keyboard) { | |
System.out.println("Displaying Keyboard."); | |
} | |
@Override | |
public void visit(Monitor monitor) { | |
System.out.println("Displaying Monitor."); | |
} | |
} |
- 最后运行一下
public class VisitorPatternDemo { | |
public static void main(String[] args) { | |
ComputerPart computer = new Computer(); | |
computer.accept(new ComputerPartDisplayVisitor()); | |
} | |
} |
# 总结
代码逻辑简单:
- 访问者有处理被访问者的行为。
- 被访问者有接收访问者并将自身引用暴露给访问者的行为。
# 参考
菜鸟教程:https://www.runoob.com/design-pattern/visitor-pattern.html?_=1478060039
Java 全栈知识体系:https://pdai.tech/md/dev-spec/pattern/20_visitor.html