标签:
观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象的状态发生改变的时候,它的所有依赖者都会收到通知,并且进行更新.
被观测的对象称为主题(Subject),观察被观测的对象的对象称为观察者(Observer).
现实中的观察者模式:例如报纸的订阅.不同人(Observer)向报社(Subject)订购报纸,当报社出品了新的报纸的时候,将会通知它的订阅者,送报纸.中途订阅者可以取消订阅,此时报社就不再给他报纸.但是只要报社一直存在,就可以有人订阅报纸.
在JavaGUI中,就有观察者模式的体现,例如Button按钮的实现.JButton会有增加和删除Listener(倾听者)的方法.
观察者模式提供了一种对象设计,让主题和观察者之间松耦合.关于观察者的一切,主题只知道观察者实现了某个接口,主题不需要知道观察者的实现类是谁,做了什么或其他任何细节.在运行时候,我们可以用新的观察者来取代现有的观察者,主题不会收到任何影响.新类型观察者出现,主题也不需要作出修改,只需要在新的类里面实现了观察者接口,然后注册为观察者即可.改变主题或观察者的任意一方,并不会影响另一方,因为两者是松耦合的,所有可以自由改变.
示例:
import java.util.ArrayList; /* * 演示主题. * */ public interface Subject { public void registerObserver(Observer o); //注册观察者 public void removeObserver(Observer o); //移除观察者 public void notifyObservers(); //主题状态发生变化的时候,通知观察者。 } class WeatherData implements Subject { private ArrayList<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); System.out.println("注册一项观察者."); } @Override public void removeObserver(Observer o) { int i=observers.indexOf(o); if(i>=0) observers.remove(o); System.out.println("移除一项观察者."); } @Override public void notifyObservers() { for (int i = 0; i < observers.size(); i++) { /* * 这里由于每个观察者都实现了Observer接口,因此我们知道如何去通知观察者来做出更新动作。 * */ observers.get(i).update(temperature, humidity, pressure); } } public void measurementsChanged() /*当状态发生改变的时候,需要通知观察者*/{ notifyObservers(); } public void setMeasurements(float temperature,float humidity,float pressure) { this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } }
/* * 演示观察者 * */ public interface Observer { public void update(float temp,float humidity,float pressure); } class CurrentConditionObserver implements Observer/*实现了观察者接口,可以获得改变。*/ { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionObserver(Subject weatherData) { this.weatherData = weatherData; //构造器需要WeatherData对象作为注册时使用。 weatherData.registerObserver(this); } @Override public void update(float temp, float humidity, float pressure) { this.temperature=temp; this.humidity=humidity; display(); } public void display() { System.out.println("Current Conditions:"+temperature+ " F degrees and "+humidity+"% humidity"); } }
/* * 测试主题和观察者.这里只用了一个观察者. * */ public class Test { public static void main(String[] args) { WeatherData data=new WeatherData(); CurrentConditionObserver obs=new CurrentConditionObserver(data); data.setMeasurements(80, 65, 30); data.setMeasurements(82, 70, 29.2f); data.setMeasurements(84, 0, 29.2f); data.removeObserver(obs); } }
类图如下:
标签:
原文地址:http://www.cnblogs.com/hlhdidi/p/5596588.html