Java 观察者模式
观察者模式(Observer):又称发布 / 订阅模式( Publish / Subscribe )。在对象之间定义了一对多的依赖,这样一来当一个对象改变状态,依赖它的对象会收到通知并自动更新。
以订阅报纸为例:
报社(订阅主题,Observable)提供报纸订阅服务,用户(订阅者,Observer)可以订阅报纸。
每当报社(订阅主题,Observable)发布新报纸时,会发到每个订阅用户(订阅者,Observer)手上。
如果用户取消订阅,那么将不再通知。
抽象 Observer:提供 update
接口,用于观察者获得订阅信息后的动作。
抽象 Observable:实现管理观察者的订阅接口(attach
增加订阅,detach
取消订阅),以及通知所有订阅的观察者(notify
)。
ConcreteObserver:具体的观察者,实现 update
接口。
ConcreteObservable:具体的订阅主题,主要做消息的发送。
观察者模式实现
抽象 Observer(订阅者)
public interface Observer {
void update(String msg);
}
抽象 Observable(订阅主题)
public abstract class Observable {
private List<Observer> mObserverList = new ArrayList();
public final void attach(Observer observer) {
mObserverList.add(observer);
}
public final void detach(Observer observer) {
mObserverList.remove(observer);
}
protected void notify(String msg) {
for (Observer observer : mObserverList) {
observer.update(msg);
}
}
}
ConcreteObserver (如报纸用户)
public class ConcreteObserver implements Observer {
@Override
public void update(String msg) {
... // 获取到 msg 的处理。比如说打印出来。
}
}
ConcreteObservable (如报社)
public class ConcreteObservable extends Observable {
private String mMsg;
public String getMsg() {
return mMsg;
}
public void setMsg(String msg){
mMsg = msg;
notify(msg);
}
}
具体调用
public static void main(String args[]) {
ConcreteObservable paper = new ConcreteObservable();
ConcreteObserver user1 = new ConcreteObserver();
ConcreteObserver user2 = new ConcreteObserver();
paper.attach(user1);
paper.attach(user2);
paper.setMsg("hello"); // 发送消息后,ConcreteObserver 会执行其 update 操作。
}
使用 Java 的观察者模式
创建 ConcreteObservable
import java.util.Observable;
public class ConcreteObservable extends Observable {
private String mMsg;
public void setMsg(String msg) {
mMsg = msg;
setChanged();
notifyObservers();
}
public String getMsg() {
return mMsg;
}
}
创建 ConcreteObserver
import java.util.Observable;
import java.util.Observer;
public class ConcreteObserver implements Observer{
@Override
public void update(Observable o, Object arg) {
ConcreteObservable concreteOb = (ConcreteObservable)o;
concreteOb.getMsg(); // 提取其信息
}
}
当然还有其它的接口,具体请看 java.util.Observable
和 java.util.Observer
观察者模式优点
对于订阅主题来说,其只知道观察者实现了 Observer 接口,并不知道(也不需要知道)它是谁?还有什么细节。
只需要通过接口发送通知,另一方进行接收。让两者之间的耦合度降低。
降低对象之间的耦合度,也是面设对象设计的一个很重要的原则、。