一、观察者模式(Observer)的定义:
观察者模式又称为订阅—发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来事件处理系统。
1、观察者模式的一般结构
首先看下观察者模式的类图描述:
观察者模式的角色如下:
Subject(抽象主题接口):定义了主题类中对观察者列表的一系列操作, 包括增加,删除, 通知等。
Concrete Subject(具体主题类):
Observer(抽象观察者接口):定义了观察者对主题类更新状态接受操作。
ConcreteObserver(具体观察者类):实现观察者接口更新主题类通知等逻辑。
从这个类图可以看出, 主题类中维护了一个实现观察者接口的类列表, 主题类通过这个列表来对观察者进行一系列的增删改操作。观察者类也可以主动调用update方法来了解获取主题类的状态更新信息。
以上的类图所描述的只是基本的观察者模式的思想, 有很多不足。比如作为观察者也可以主动订阅某类主题等。下面的例子将进行一些改动, 以便适用具体的业务逻辑。
2、观察者模式示例
我们构建一个观察者和主题类, 观察者可以主动订阅主题或者取消主题。主题类统一被一个主题管理者所管理。下面给出类图:
Subject:
public interface Subject {
//注册一个observer
public void register(Observer observer);
//移除一个observer
public void remove(Observer observer);
//通知所有观察者
public void notifyObservers();
//获取主题类要发布的消息
public String getMessage();
}
ConcerteSubject:
public class MySubject implements Subject {
private List observers;
private boolean changed;
private String message;
//对象锁, 用于同步更新观察者列表
private final Object mutex = new Object();
public MySubject() {
observers = new ArrayList();
changed = false;
}
@Override
public void register(Observer observer) {
if (observer == null)
throw new NullPointerException();
//保证不重复
if (!observers.contains(observer))
observers.add(observer);
}
@Override
public void remove(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
// temp list
List tempObservers = null;
synchronized (mutex) {
if (!changed)
return;
tempObservers = new ArrayList<>(this.observers);
this.changed = false;
}
for(Observer obj : tempObservers) {
obj.update();
}
}
//主题类发布新消息
public void makeChanged(String message) {
System.out.println("The Subject make a change: " + message);
this.message = message;
this.changed = true;
notifyObservers();
}
@Override
public String getMessage() {
return