设计模式整理_观察者模式
Posted 大胡龙的小圈子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式整理_观察者模式相关的知识,希望对你有一定的参考价值。
观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象的状态发生改变的时候,它的所有依赖者都会收到通知,并且进行更新.
被观测的对象称为主题(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); } }
类图如下:
实际上Java为我们提供了观察者和被观察者的便捷实现,即Observable类和Observer接口,被观察者只需要继承Observable类即可实现被观察的功能,而观察者只需要实现Observable接口即可.下面是示例,利用Java给定的观察者和被观察者对象,对代码做出了调整:
/* * 演示主题. * */ import java.util.Observable; class WeatherData extends Observable { private float temperature; private float humidity; private float pressure; //不再需要继承观察者而建立数据结构了.实际上Observable类已经为我们做好了这件事情. public WeatherData() { } public float getTemperature() { return temperature; } public float getHumidity() { return humidity; } public float getPressure() { return pressure; } public void measurementsChanged() /*当状态发生改变的时候,需要通知观察者*/{ setChanged(); //调用notifyObservers方法之前,需要先调用setChanged来指示状态改变 notifyObservers(); } public void setMeasurements(float temperature,float humidity,float pressure) { this.temperature=temperature; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } }
import java.util.Observable; import java.util.Observer; /* * 演示观察者 * */ class CurrentConditionObserver implements Observer/*实现了观察者接口,可以获得改变。*/ { private float temperature; private float humidity; Observable obs; public CurrentConditionObserver(Observable weatherData) { this.obs = weatherData; //构造器需要Observable对象作为注册时使用。 weatherData.addObserver(this); } public void display() { System.out.println("Current Conditions:"+temperature+ " F degrees and "+humidity+"% humidity"); } @Override public void update(Observable o, Object arg) { //覆盖update方法,从Observable对象中获取值 if(o instanceof WeatherData) { WeatherData data=(WeatherData) o; this.temperature=data.getTemperature(); this.humidity=data.getHumidity(); display(); } } }
但是实际上Java提供的这种机制是有缺陷的,因为Observable是一个类,因此只能继承来实现,这要求被观察的对象没有父类,另外一方面,也违反了设计模式当中的"多用组合,少用继承的原则,因此,有必要的时候,还是需要自己来实现观察者对象和被观察者对象.
以上是关于设计模式整理_观察者模式的主要内容,如果未能解决你的问题,请参考以下文章
扎实基础_设计模式_行为型_观察者模式(项目实战,使用委托注册事情,消除多重判断)