设计模式(1) - 观察者模式
实现
实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。

观察者
(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
被观察
被观察对象发生了某种变化(如图中的measurementsChange),从容器中得到所有注册过的观察者,将变化通知观察者。
撤销观察
观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现——这一点为程序提供了更大的灵活性。
//观察者接口 interface Observer { //由被观察者调用观察者,通知观察者状态修改 void update(float... params); } //收到状态改变通知后响应接口 interface DisplayElement { //观察者收到通知后具体响应操作 void display(); } //被观察者接口 interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObserver(); } class WeatherData implements Subject { private ArrayList<Observer> observers; //观察者的容器 private float[] container; private transient int default_size = 1 << 10; public WeatherData() { observers = new ArrayList<Observer>(); } public WeatherData(List<Observer> observers) { if (observers != null && observers.size() >= 0) { this.observers = (ArrayList<Observer>) observers; } else { throw new NullPointerException(); } } //向被观察者注册 @Override public void registerObserver(Observer o) { observers.add(o); } //撤销注册 @Override public void removeObserver(Observer o) { int index = observers.indexOf(o); if (index >= 0) { observers.remove(index); } } //将状态告诉每一个观察者 @Override public void notifyObserver() { for (int i = 0; i < observers.size(); i++) { Observer observer = (Observer) observers.get(i); observer.update(container); } } public void measurementsChanged() { this.notifyObserver(); } public void setMeasurements(float... params) { setParams(params); measurementsChanged(); } public void setParams(float... params) { int length = params.length; if (length <= 0) { throw new NullPointerException(); } else if (length < default_size) { params = new float[default_size]; } else { default_size = length; params = new float[default_size]; } System.arraycopy(params, 0, params, 0, length); } } class CurrentConditionsDisplay implements Observer,DisplayElement{ private float[] params; private transient int default_size = 1 << 10; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void update(float... params) { setParams(params); display(); } public void setParams(float... params) { int length = params.length; if (length <= 0) { throw new NullPointerException(); } else if (length < default_size) { params = new float[default_size]; } else { default_size = length; params = new float[default_size]; } System.arraycopy(params, 0, params, 0, length); } @Override public void display() { //do something } }
注:jdk 自带了观察者模式的实现,具体可以百度实现

浙公网安备 33010602011771号