设计模式学习系列3 观察者模式
观察者模式,又称为发布订阅模式,收听模式等,该模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新,下面的代码主要参考《大话设计模式》这本书,我用C++写了一边,并且做了一些修改和优化。
故事背景:无
故事的逻辑:观察者的状态修改的时候 ,通知依附于它本身的被通知者,通知者收到状态修改的信息之后作出状态修改的信息输出
/*设计模式学习系列之观察者模式 * 参考书籍《大话设计模式》 * 观察者莫模式的主要用途:当一个对象的改变需要同时改变其他对象状态的时候,该模式 * 可以将二者解除耦合,使二者独立的进行改变和复用 * * 例子的架构:通知者与被通知者,通知者保留被统治者的列表,被通知者得到通知后 更改自己的状态 */ #include <iostream> using namespace std ; #include <vector> //被通知者抽象类 class Subject { private: unsigned int m_id ; public: Subject():m_id(0){} virtual ~Subject(){} void SetId(const unsigned int& id){m_id = id ;} unsigned int GetId(){return m_id;} //更新状态 ,虚函数,需要使用子类自己实现 virtual void UpdateState(){ cout << "base class\n" << endl; } }; //通知者抽象类 class Observe { private: vector<Subject*> m_SubjectList; public: Observe(){} virtual ~Observe(){} //增加被通知者 void Attach( Subject* sub ) { m_SubjectList.push_back(sub); } //删除被通知者 void Detach( Subject* sub) { vector<Subject*>::iterator it = m_SubjectList.begin(); for( ; it != m_SubjectList.end() ; ++it) { if( (*it)->GetId() == sub->GetId()) { m_SubjectList.erase(it); } } } //通知所有对象 void Update() { vector<Subject*>::iterator it = m_SubjectList.begin(); for( ; it != m_SubjectList.end() ; ++it) { (*it)->UpdateState(); } } }; //观察者 实现类 class Observe1:public Observe { public: void SetState(const string & str) { m_State = str ; } string GetState() { return m_State; } private: string m_State ; } ; //被通知者1 class Subject1:public Subject { private: string m_strState ; Observe m_Observe ; public: Subject1(const Observe1 &obs ,const int& id) { m_Observe = obs ; SetId(id); } ~Subject1(){} void UpdateState() { cout << "Subject1 收到通知,通知内容:" << endl ; } } ; //被通知者2 class Subject2:public Subject { private: string m_strState ; Observe m_Observe ; public: Subject2(const Observe1 &obs ,const int& id) { m_Observe = obs ; SetId(id); } ~Subject2(){} void UpdateState() { cout << "Subject2 收到通知,通知内容:" << endl ; } }; //============================================================== int main() { Observe1 obs ; Subject1 *pSub1 = new Subject1(obs,1); Subject2 *pSub2 = new Subject2(obs,2); obs.Attach(pSub1); obs.Attach(pSub2); obs.SetState("xxxxxx"); obs.Update(); return 0 ; }
记录一下实现过程中遇到的问题:
(1)被通知者列表为指针类型,这样才会使用虚函数的特性,观察者进行通知的时候会通知被观察者的子类而不是基类
(2)基类的析构函数为虚函数,析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。
(3)上述方法中 被通知者不一定要记录观察者的信息,只要作出自己的修改
细雨淅淅 标签: 设计模式