Visitor Design Pattern(访问者设计模式)实现要点:
所有被访问的对象必须继承一个带有accept(IVisitor)方法的接口;
被访问对象的accept方法的具体实现:visitor.visit(this), 把自己的对象暴露给visitor;
访问的对象通过实现IVisitor接口,对不同的被访问对象子类进行不同的操作。
好处:
1,分散在不同子类相同的功能被集中管理在一种Visitor类中,数据结构和操作分离。
2,避免使用大量的 instanceof 即可完成对各种子类的访问。
更多好处还没理解和发现。。。。。。 (思考中)
具体的例子(包含component design pattern)
VisitorDemo.java
package com.dp.visitor;
interface CarElementVisitor {
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
interface CarElement {
void accept(CarElementVisitor visitor); // CarElements have to provide accept().
}
class Wheel implements CarElement {
private String name;
public Wheel(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Engine implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Body implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Car implements CarElement{
CarElement[] elements;
public CarElement[] getElements() {
return elements.clone(); // Return a copy of the array of references.
}
public Car() {
this.elements = new CarElement[]
{ new Wheel("front left"), new Wheel("front right"),
new Wheel("back left") , new Wheel("back right"),
new Body(), new Engine() };
}
public void accept(CarElementVisitor visitor) {
for(CarElement element : this.getElements()) {
element.accept(visitor);
}
visitor.visit(this);
}
}
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Visiting "+ wheel.getName()
+ " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
class CarElementDoVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Kicking my "+ wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Starting my engine");
}
public void visit(Body body) {
System.out.println("Moving my body");
}
public void visit(Car car) {
System.out.println("Starting my car");
}
}
public class VisitorDemo {
public static void main(String[] args) {
Car car = new Car();
car.accept(new CarElementPrintVisitor());
System.err.println("\n====================\n");
car.accept(new CarElementDoVisitor());
}
}
更多阅读:
使用反射简化double dispatch的模拟:
In the Java language, two techniques have been documented that use reflection to simplify the mechanics of double dispatch simulation in the visitor pattern: getting rid of accept() methods (the Walkabout variation), and getting rid of extra visit() methods.
参考:
http://en.wikipedia.org/wiki/Visitor_pattern
分享到:
评论