模式定义
观察者模式将类的结构与操作于该类上的算法分离开,使得模式的使用者能在不改变类结构的前提下自由地对类中的元素进行不同的操作。
使用方法

Visitor将自己注册到类对象中,由类对象通过回调的方式来启动观察者访问操作类内部的数据元素或结构。
使用范围
- 类结构内部包含很多具有不同接口的类对象,需要定义针对于具体类的操作
- 需要对于类结构中的类对象定义不同的操作
- 需要重新定义或扩展对类结构中的类对象的操作
举例说明
假设定义一个汽车的复杂的类结构Car以及Car的组件Engine, Wheel,均作为CarElement的元素存在。
public interface CarElement { void accept(CarElementVisitor visitor); } -------- public class Wheel implements CarElement{ private String name; Wheel(String name){ this.name = name; } public String getName(){ return name; } public void accept(CarElementVisitor visitor) { visitor.visit(this); } } -------- public class Engine implements CarElement{ public void accept(CarElementVisitor visitor) { visitor.visit(this); } } -------- public class Car implements CarElement{ CarElement[] elements; public CarElement[] getElements(){ return elements.clone(); } public void accept(CarElementVisitor visitor) { visitor.visit(this); } Car(){ this.elements = new CarElement[]{ new Engine(), new Wheel("front two wheels"), new Wheel("back two wheels") }; } }
每个CarElement的实现类均通过accept()的方法来回调visitor并访问自身。
接下来即可定义一个visitor类,比如Driver。为了使得visitor具有可扩展可延续性,可以将Driver抽象出一个接口来,之后可以根据不同的需求来定义不同的Driver。观察Driver类是如何将自己作为参数注入Car类结构的。
interface CarElementVisitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Car car); } -------- public class Driver implements CarElementVisitor{ public void visit(Wheel wheel) { System.out.println("Rolling " + wheel.getName()); } public void visit(Engine engine) { System.out.println("Starting engine"); } public void visit(Car car) { System.out.println("I am driving"); for (CarElement ele:car.getElements()){ ele.accept(this); } System.out.println("going..."); } }
最后用一个具体的调用过程来实现visitor。
public class CarVisitorClient { public static void main(String args[]){ Car car = new Car(); car.accept(new Driver()); } }
下载示例