Visitor 观察者模式

本文介绍了一种设计模式——观察者模式,它将类结构与操作分离,允许在不修改类结构的情况下自由操作类中的元素。文章通过一个汽车类结构的例子详细展示了如何实现观察者模式,并解释了其工作原理。

模式定义

 

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

使用方法

 


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());
	}
}

下载示例

 

下面是观察者模式Java 代码示例: ``` import java.util.ArrayList; import java.util.List; // 主题接口 interface Subject { // 注册观察者 void registerObserver(Observer observer); // 移除观察者 void removeObserver(Observer observer); // 通知观察者 void notifyObservers(); } // 观察者接口 interface Observer { // 接收通知 void update(String message); } // 具体主题 class ConcreteSubject implements Subject { // 观察者列表 private List<Observer> observers = new ArrayList<>(); // 状态 private String state; // 设置状态 public void setState(String state) { this.state = state; // 状态改变时通知观察者 notifyObservers(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(state); } } } // 具体观察者 class ConcreteObserver implements Observer { // 名称 private String name; public ConcreteObserver(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + " 收到消息:" + message); } } // 测试类 public class ObserverPatternDemo { public static void main(String[] args) { // 创建具体主题 ConcreteSubject subject = new ConcreteSubject(); // 创建具体观察者 ConcreteObserver observer1 = new ConcreteObserver("Observer1"); ConcreteObserver observer2 = new ConcreteObserver("Observer2"); ConcreteObserver observer3 = new ConcreteObserver("Observer3"); // 注册观察者 subject.registerObserver(observer1); subject.registerObserver(observer2); subject.registerObserver(observer3); // 设置状态,观察者将收到通知 subject.setState("Hello World!"); } } ``` 在这个例子中,`ConcreteSubject` 是具体主题,`ConcreteObserver` 是具体观察者。`Subject` 是主题接口,定义了注册、移除、通知观察者等方法。`Observer` 是观察者接口,定义了接收通知的方法。当主题的状态改变时,它会通知所有的观察者。在测试类中,我们创建了具体主题和具体观察者,并注册观察者到主题中,然后设置状态,观察者将收到通知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值