观察者模式
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新;
从上述描述中,我们可知观察者模式主旨是一对多的关系,多个隔离性的对象依赖与一个独特对象,需要获取该对象实时状态;
这个情景如同订阅报纸行为:
报社的业务就是出版报纸;(独特功能对象)向报社订阅报纸,有新报纸出版,就会向你送来报纸,只要你是他们的订户;当取消订阅时,它们将停止给你派送报纸;只要报社运营着,就会有人向他们订阅或者取消订阅;从上述类图中,可以看出观察者模式最关键实现部分是两个接口的使用;
举个栗子: 主题接口,也可称为可观察者接口 Observerable
public interface Observerable { //注册观察者资格 public void registerObserver(Observer observer); //取消观察者资格 public void removeObserver(Observer observer); //可观察者状态通知 public void notifyObserver(); }观察者接口 Observer
public interface Observer { public void update(float temperature, float humidity, float pressure); }可观察者对象实现 WeatherData
public class WeatherData implements Observerable { private float temperature; private float humidity; private float pressure; private ArrayList<Observer> observers;//观察者队列 public WeatherData() { observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { int i = observers.indexOf(observer); if(i > 0) { observers.remove(i); } } @Override public void notifyObserver() { for (Observer o : observers) { o.update(this.temperature, this.humidity, this.pressure); } } public void measurementsChange() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChange(); } }观察者对象 CurrentConditionDisplay
public class CurrentConditionDisplay implements Observer, DisplayElement { private float temperature; private float humidity; private Observerable weatherData; public CurrentConditionDisplay(Observerable weatherData) { this.weatherData = weatherData; this.weatherData.registerObserver(this); } @Override public void display() { System.out.println("Current condition:" + this.temperature + "F degrees and " + this.humidity + "% humidity."); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } }通过上述的解耦,当观察者对象任意增加时我们只需要调用可观察者对象registerObserver()进行注册即可得到可观察者对象的变化,同样也可以依据自身需要进行取消观察;
对于观察者模式的实现,JDK已经提供比较完善的支持: 可观察者对象: Observable
public class Observable { private boolean changed = false; private Vector obs; public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); } }观察者对象:
public interface Observer { void update(Observable o, Object arg); }通过上面JDK源码查阅,基本所实现的功能都是一模一样的,Observable对象更是提供线程安全的保证,只是采用继承的实现方法给我们自身进行应用带来一点麻烦;