[GeekBand] 设计模式之观察者模式学习笔记
本文参考文献::GeekBand课堂内容,授课老师:李建忠
:网络资料: http://blog.csdn.net/hguisu/article/details/7556625
本文仅作为自己的学习笔记,不代表权威,因为是初学,有错误烦请大家指正,谢谢。
1、什么是观察者模式,应用场所有哪些?
观察者模式(有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
--------360百科定义
2、结构
3、通过代码分析,模式的组成
如上图所示:观察者模式包含如下角色:
目标(Subject): 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。
//目标: 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。 Class Form { public: virtual void Attach(FileSpliter* observer);//注册观察者 virtual void Detach(FileSpliter* observer);//释放观察者 virtual void Notify();//通知所有注册的观察者 interface SplObserver { virtual void Update(Form *) = 0; //观察者进行更新状态 }; }
具体目标(ConcreteSubject): 将有关状态存入各ConcreteObserver对象。
//具体目标(MainForm): 将有关状态存入各MainForm对象 class MainForm : public Form { public: /** * 释放观察者 */ virtual void Attach(FileSpliter* observer) { _observers->Append(observer); } /** * 注册观察者 */ virtual void Detach(FileSpliter* observer) // { _observers->Remove(observer); }; /** * 通知所有观察者 */ virtual void Notify() { for obs in _observers //遍历 { if (observers->getState() == this->State) { obs->Update(this); } } }; //设置状态 void Button1_Click(bool State) { this->State = State; //状态改变 Notify(); } protected: MainForm() {} private: TestBox* txtFilePath; TextBox* txtFileNumber; ProgressBar* progressBar; List<FileSpliter*> *_observers; };
观察者(Observer): 为那些在目标发生改变时需获得通知的对象定义一个更新接口。当它的状态发生改变时, 向它的各个观察者发出通知。
/** * 抽象观查者 * */ class FileSplitter { public: virtual void Split() = 0; virtual void Update(MainForm*) = 0; virtual ~FileSplitter() {} protected: virtual void onProgress(float value) { List<FileSpliter*>::iterator itor = _observers.begin(); while (itor != _observers.end()) (*itor)->DisplayProgress(value); //更新进度条 itor++; } void DisplayProgress(int value) { progressBar->setValue(value); } } private: string filePath; int fileNumber; bool State; };
具体观察者(ConcreteObserver): 维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。
//具体观察者1 class Spliter1 : public FileSplitter { public: Spliter1(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter1() { _subject->State = false _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //1、打开文件filePath //2、把文件分割成fileNumber个文件 //3、DisplayProgress重载,以1的方式更新进度(如进度条) DisplayProgress(value); } private: bool State; MainForm* _subject; }; //具体观察者2 class Spliter2 : public FileSplitter { public: Spliter2(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter2() { _subject->State = false; _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //1、打开文件filePath //2、把文件分割成fileNumber个文件 //3、DisplayProgress重载,以2的方式更新进度(如控制台...) DisplayProgress(value); private: MainForm* _subject; bool State; }; //具体观察者3 class Spliter3 : public FileSplitter { public: Spliter3(MainForm* mf) { _subject = mf; _subject->State = true; _subject->Attach(this); } virtual ~Spliter3() { _subject->State = false; _subject->Detach(this); } virtual void Update(MainForm *mf) { _subject->State = true; if (mf == _subject) { Split() } } virtual void Split() { //1、打开文件filePath //2、把文件分割成fileNumber个文件 //3、DisplayProgress重载,以3的方式更新进度(如百分比) DisplayProgress(value); } private: MainForm* _subject; bool State; };
main函数
nt main() { MainForm* mf = new MainForm(); Spliter1* sp1 = new Spliter1(mf); Spliter2* sp2 = new Spliter2(mf); Spliter3* sp3 = new Spliter3(mf); return 0; }
4、总结
1、通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。
2、观察者模式符合开闭原则,开闭原则是指一个软件实体应该对扩展开放,对修改关闭。也就是说软件实体必须是在不被修改的情况下被扩展。模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用。
3、
模板方法模式与对象的封装性,面向对象的三大特性:继承,封装,多态。
对象有内部状态和外部的行为。封装是为了信息隐藏,通过封装来维护对象内部数据的完整性。使得外部对象不能够直接访问一个对象的内部状态,而必须通过恰当的方法才能访问。在C++中,采用给对象属性和方法赋予指定的修改符(public、protected、private)来达到封装的目的,使得数据不被外部对象恶意的访问及方法不被错误调用导造成破坏对象的封装性。