一、观察者模式:
观察者模式(observe)(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。观察者模式定义了对象间的一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
二、观察者模式中的对象:
1、抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
2、抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
3、具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
4、具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
三、天气预报观察者模式实现原理:
四、天气预报观察者模式代码:
1、观察者接口
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public interface Observer { public void update(float temperature, float humidity, float pressure); }
2、具体的观察者角色
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public class StatisticsDisplay implements DisplayElement, Observer { @Override public void update(float temperature, float humidity, float pressure) { // TODO Auto-generated method stub } @Override public void display() { // TODO Auto-generated method stub } }
3、抽象被观察者角色
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public interface Subject { public void registerObserver(Observer o); public void unregisterObserver(Observer o); public void notifyObserver(); }
4、天气数据
/** * */ package org.java.ObserverPattern; import java.util.ArrayList; /** * @author SUSHMARAVI * */ public class WeatherData implements Subject{ float temperature; float humidity; float pressure; ArrayList<Observer> observers; public WeatherData(){ observers = new ArrayList<Observer>(); } public float getTemperature() { return temperature; } public void setWeatherData(float temperature,float humidity,float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; notifyObserver(); } public float getHumidity() { return humidity; } public float getPressure() { return pressure; } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void unregisterObserver(Observer o) { int i = observers.indexOf(o); if(i>=0) observers.remove(o); } @Override public void notifyObserver() { for(Observer obs: observers){ obs.update(temperature, humidity, pressure); } } }
5、气象站管理天气数据
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public class WeatherStation { /** * @param args */ public static void main(String[] args) { WeatherData wd = new WeatherData(); CurrentConditionDisplay ccd = new CurrentConditionDisplay(wd); StatisticsDisplay sd = new StatisticsDisplay(); ForecastDisplay fd = new ForecastDisplay(); wd.setWeatherData(87, 5, 10); wd.setWeatherData(90, 7, 8); wd.setWeatherData(82, 3, 12); } }
6、天气显示接口
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public class ForecastDisplay implements DisplayElement, Observer { float temperature, humidity, pressure; public Subject weatherData; @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; display(); } @Override public void display() { // TODO Auto-generated method stub } }
7、显示此时的天气状态
/** * */ package org.java.ObserverPattern; /** * @author SUSHMARAVI * */ public class CurrentConditionDisplay implements DisplayElement, Observer { float temperature, humidity, pressure; public Subject weatherData; public CurrentConditionDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; display(); } @Override public void display() { System.out.println("Current weather conditions: \ntemperature = "+temperature+"\nhumidity = "+humidity+"\npressure = "+pressure); } }
五、观察者模式的优缺点:
1、优点
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
2、缺点
(1)如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
六、GitHub原码链接:https://github.com/csushma/ObserverPattern/tree/master/src/org/java/ObserverPattern