观察者模式:类似于出版者+订阅者模式
出版者提供数据,当数据有改变的时候,就将变化推送给订阅者。
订阅者可以要求自己添加到观察者对象中,也可以要求被移除出这个集合。
观察者模式定义了对象之间的一对多的依赖关系,当一个对象改变时,它所有的依赖者都要需要进行改变,并进行自动更新。
原则:为交互对象之间的松耦合。这是一个很好的例子。
对于一个气象监测应用的概况,主要包括三个部分,气象站(提供数据), weatherdata对象(数据来自于气象站),布告板(可定制化展示的内容)
很符合观察者的设计模式,
对象之间是一对多的关系,当气象站的数据发生改变时,weatherdata对象也要发生改变。
可观察者(被观察者):
class Subject { public: Subject(); ~Subject(); register_observer(Observer *o); //将观察者注册到主题的待通知数组中 remove_observer(Observer *o); //移除观察者 Notify_observer(); //遍历,通知观察者 }; class WeatherData:public Subject { public: WeatherData(); ~WeatherData(); int get_tempaure(); int get_press(); int get_humi(); weatherdata_changed(int temp, int press, int huimi) //具体的业务实现 { m_tempaure = temp; m_press = m_press; m_humi = huimi; set_changed(); } set_changed() { Notify_observer(); } Notify_observer() { //用迭代器实现,遍历保存的的观察者对象,然后将数据更新到观察者对象中 } private: vector<Observer> m_save_observer; int m_tempaure; int m_press; int m_humi; };
观察者:
class Observer { public: Observer(); ~Observer(); void update(); }; class Display_interface { public: Display_interface(); ~Display_interface(); private: void display(); }; class Weather_condition :public Observer, public Display_interface { public: Weather_condition(Subject *s) //在里面实现注册接口 { m_s = s; s.register_observer(this); } ~Weather_condition() { } void update(int tmpure, int press, int humi) { m_tmpure = tmpure; m_press = press; m_huimi = huimi; } void display(); private: Subject *m_s; int m_tmpure; int m_press; int m_huimi; };
观察者是observer, 同时还有展示部分,这三者是松耦合的。(重要)
当两个对象进行松耦合时,它们可以交互,但是不太清楚彼此的细节。观察者模式提供了一种设计,让主题和观察者之间进行松耦合。
学习总结的内容:
1、可观察者 定义了一个统一的接口来更新观察者,对应各个观察者的update接口
2、松耦合,可观察者 不知道观察者实现的细节,只知道观察者的接口。
3、用这个设计模式的时候,可以推,也可以拉,具体场景具体分析。
4、有多个观察者的时候,不依赖于特定的通知顺序。
引发的思考:
展示部分由于是可定制的,因此单独抽象出一个接口来,没有和每一个观察者绑定在一起。支持可扩展。