首页
学习
活动
专区
圈层
工具
发布

[设计模式]之十六:观察者模式

定义

观察者模式又叫发布订阅模式(public/subscribe),定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

UML

示例代码

代码语言:javascript
复制
//抽象出Notifier接口,保持所有被观察者对象的引用,并管理通知 notify
abstract class INotifier {
	private List<IObserver> observers = new ArrayList<>();
	
	public void attach(IObserver observer) {
		observers.add(observer);
	}
	
	public void detach(IObserver observer) {
		observers.remove(observer);
	}
	
	public void notifyObserver() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update();
		}
	}
}
// 具体的通知者 管理控制具体的观察者对象  管理自己需要变化的状态
public class ConcreteNotifier extends INotifier {
	private String state;

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
	
}
//抽象观察者。观察者需要在得到通知后更新自己 所以需要更新方法
abstract class IObserver {
	// 更新接口
	public abstract void update();
}
//具体观察者 它会有一个状态  在update的时候从对应的notifier获取新状态
public class ConcreteObserver extends IObserver {

	private String name;
	private String observerState;
	private ConcreteNotifier notifier;

	public ConcreteObserver(ConcreteNotifier notifier, String name) {
		// TODO Auto-generated constructor stub
		this.notifier = notifier;
		this.name = name;
	}
	
	@Override
	public void update() {
		// TODO Auto-generated method stub
		observerState = notifier.getState();
		System.out.println("Observer " + name + "'s new state is " + observerState);
	}

}

//客户代码
public void start() {
    //创建通知者
	ConcreteNotifier notifier = new ConcreteNotifier();
	//添加观察者
	notifier.attach(new ConcreteObserver(notifier, "X"));
	notifier.attach(new ConcreteObserver(notifier, "Y"));
	//通知更新状态
	notifier.setState("hahaha");
    //告诉观察者开始改状态
	notifier.notifyObserver();
}
//输出
Observer X's new state is hahaha
Observer Y's new state is hahaha

评价

一个对象改变需要同时改变其他对象的时候,且它不知道具体有多少对象有待改变时,考虑使用观察者模式。

观察者模式做的工作其实就是在解耦合,让耦合双方都依赖抽象,而不是依赖具体。从而使得各自变化都不会影响另一边变化。

但上面代码还有一个小问题,就是INotifier依赖IObserver。如果通知者和观察者互相不知道对方,由客户端来决定,那么就会更灵活。所以还需要一层解耦。

https://www.kancloud.cn/digest/suski-pattern/160469

下一篇
举报
领券