定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的的对象都会收到通知,并自动更新。
类图:
要点:
1.主题(可观察者)用一个共同的接口来更新观察者。
2.观察者与可观察者之间用松耦合方式结合(loosecoupling),可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
3.使用此模式时,你可以被观察者处推(push)或拉(pull) 数据(然而,推的方式被认为更“正确”)。
4.有多个观察者时,不可以依赖特定的通知次序。
5.Java有多种观察者模式的实现,包括了通用的java.util.Observable。
6.要注意java.util.Observable实现上所带来的一些问题。
7.如果有必要的话,可以实现自己的Observable,这并不难。
8.Swing大量使用观察者模式,许多GUI框架也是如此。
9.此模式也被应用在许多地方,例如JavaBeans,RMI。
public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObserver(); }
public interface Observer{ public void update(float temp, float humidity, float pressure); }
public class WeatherData implements Subject{ private List<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData(){ observers = new ArrayList<Observer>(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { int i = observers.indexOf(o); if(i>= 0){ observers.remove(i); } } @Override public void notifyObserver() { for(Observer observer : observers){ observer.update(temperature, humidity, temperature); } } public float getTemperature(){ return this.temperature; } public float getHumidity(){ return this.humidity; } public float getPressure(){ return this.pressure; } public void measurementsChanged(){ notifyObserver(); } public void serMeasurements(float temperature, float humidity, float pressure){ this.humidity = humidity; this.temperature = temperature; this.pressure = pressure; measurementsChanged(); } }
public class CurrentConditionsDisplay implements Observer, DisplayElement{ private float temperature; private float humidity; public CurrentConditionsDisplay(){ } @Override public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity"); } @Override public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } }