一:观察者模式
1.什么是观察者模式?
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
观察者模式的基本介绍
又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
2.观察者模式适合应用场景
1.当一个对象状态的改变需要改变其他对象, 或实际对象是事先未知的或动态变化的时, 可使用观察者模式。
2.当应用中的一些对象必须观察其他对象时, 可使用该模式。 但仅能在有限时间内或特定情况下使用。
3.观察者模式优缺点
优点:
1.开闭原则。 你无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
2.你可以在运行时建立对象之间的联系。
缺点:
1.订阅者的通知顺序是随机的。
4.观察者模式角色:
Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
二:观察者模式代码实现
抽象被观察者
//(抽象被观察者)接口, 让(具体观察者)WeatherData 来实现public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObservers();}
具体被观察者
/** * 类是核心 * 1. 包含最新的天气情况信息* 2. 含有 观察者集合,使用ArrayList管理 * 3. 当数据有更新时,就主动的调用 ArrayList, 通知所有的(接入方)就看到最新的信息 * @author Administrator * *////具体被观察者public class WeatherData implements Subject {private float temperatrue;private float pressure;private float humidity;//观察者集合private ArrayList<Observer> observers;//加入新的第三方public WeatherData() {observers = new ArrayList<Observer>();}public float getTemperature() {return temperatrue;}public float getPressure() {return pressure;}public float getHumidity() {return humidity;}public void dataChange() {//调用 接入方的 updatenotifyObservers();}//当数据有更新时,就调用 setDatapublic void setData(float temperature, float pressure, float humidity) {this.temperatrue = temperature;this.pressure = pressure;this.humidity = humidity;//调用dataChange, 将最新的信息 推送给 接入方 currentConditionsdataChange();}//注册一个观察者@Overridepublic void registerObserver(Observer o) {// TODO Auto-generated method stubobservers.add(o);}//移除一个观察者@Overridepublic void removeObserver(Observer o) {// TODO Auto-generated method stubif(observers.contains(o)) {observers.remove(o);}}//遍历所有的观察者,并通知@Overridepublic void notifyObservers() {// TODO Auto-generated method stubfor(int i = 0; i < observers.size(); i++) {observers.get(i).update(this.temperatrue, this.pressure, this.humidity);}}}
抽象观察者
//抽象观察者接口,由具体观察者来实现()public interface Observer {public void update(float temperature, float pressure, float humidity);}
具体观察者
//具体观察者public class BaiduSite implements Observer {// 温度,气压,湿度private float temperature;private float pressure;private float humidity;// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}// 显示public void display() {System.out.println("===百度网站====");System.out.println("***百度网站 气温 : " + temperature + "***");System.out.println("***百度网站 气压: " + pressure + "***");System.out.println("***百度网站 湿度: " + humidity + "***");}}//具体观察者public class CurrentConditions implements Observer {// 温度,气压,湿度private float temperature;private float pressure;private float humidity;// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式public void update(float temperature, float pressure, float humidity) {this.temperature = temperature;this.pressure = pressure;this.humidity = humidity;display();}// 显示public void display() {System.out.println("***Today mTemperature: " + temperature + "***");System.out.println("***Today mPressure: " + pressure + "***");System.out.println("***Today mHumidity: " + humidity + "***");}}
测试
public static void main(String[] args) {// TODO Auto-generated method stub//创建一个WeatherDataWeatherData weatherData = new WeatherData();//创建观察者CurrentConditions currentConditions = new CurrentConditions();BaiduSite baiduSite = new BaiduSite();//注册到weatherDataweatherData.registerObserver(currentConditions);weatherData.registerObserver(baiduSite);//测试System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);weatherData.removeObserver(currentConditions);//测试System.out.println();System.out.println("通知各个注册的观察者, 看看信息");weatherData.setData(10f, 100f, 30.3f);}