9.观察者模式

来源:互联网 发布:udid定制后台源码 编辑:程序博客网 时间:2024/05/22 11:50

1.说明
请参阅该系列第一篇文章。
2.观察者模式说明
观察者模式:定义了一种一对多的关系,让多个观察者对象监听某一主题对象,这个主体对象发生改变时,会通知观察者对象,使他能够自动更新自己
特点:将一个系统分割成一系列相互协作的类是一个很不好的副作用,那就是需要维护相关对象的一致性,我们不希望为了维护类的一致性而使类紧密耦合,这样会给维护,扩展,重用带来很多不便。
使用场景:当一个对象的改变需要需要同时改变其他对象,而且他不知道有多少个对象需要改变,这个时候就应该使用观察者模式,发出通知即可
作用:解除类之间的耦合,让耦合的双方都依赖于抽象,而不是具体的。
另外一种重要的方式:使用委托(待看)
委托对象所搭载的方式,必须具备于原来的有相同的形式,参数列表,返回值类型
公司项目就是通过观察者模式构建的,要扩展的时候,直接进行挂载,感觉很方便
3.UML
这里写图片描述
4.代码
代码背景:
在一个公司中,有老板,leader,员工A,B。老板管理leader,A,B。Leader管理A,B。A,B的上级有leader,老板,当其中任意一个对象状态发生改变,A,B状态也发生改变。在真正的项目中可能不会这么复杂,此处只是模拟现实中状况

//观察者基类#ifndef __SUBJECT_H#define __SUBJECT_H#include <iostream>#include <list>#include "Observer.h"class CSubject{public:    void add(CObserver* obser)    {        m_objlist.push_back(obser);    }    void del(CObserver* obser)    {        for (std::list<CObserver*>::iterator it=m_objlist.begin(); it!=m_objlist.end(); it++)        {            if ((*it)->getname() == obser->getname())            {                           m_objlist.erase(it);                break;              }           }    }    void notify()    {        for (std::list<CObserver*>::iterator it=m_objlist.begin(); it!=m_objlist.end(); it++)        {            (*it)->notify();        }    }    virtual std::string get_subject_status() = 0;    virtual int get_subflag() = 0;private:    std::list<CObserver*> m_objlist;};#endif //观察者 大boss#ifndef __BIGBOSS_H#define __BIGBOSS_H#include "Subject.h"class CBigBoss:public CSubject{public:    CBigBoss(std::string name)    {        m_flag = 0;        m_name = name;    }    std::string get_subject_status()    {        return "BigBoss BACK";    }    void action()    {        m_flag = 1;        notify();        m_flag = 0;    }    int get_subflag()    {        return m_flag;    }private:    std::string m_name;    int m_flag;};#endif//即是观察者也是统治者的 TM leader#ifndef __BOSS_H#define __BOSS_H#include "Subject.h"#include "Observer.h"class CBoss:public CSubject,public CObserver{public:    CBoss(std::string name)    {        m_flag = 0;        m_name = name;    }    std::string get_subject_status()    {        return "TM Leader BACK";    }    void action()    {        m_flag = 1;        notify(1);        m_flag = 0;    }    int get_subflag()    {        return m_flag;    }    std::string getname()    {        return m_name;    }public:    void add_sub(CSubject* ober)    {        m_sublist.push_back(ober);    }    void notify(int x)    {        CSubject::notify();    }    void notify()    {         //大老板发通知后,拍着马屁也发通知        std::cout<<"I recved big boss notify"<<std::endl;        CSubject::notify();        for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++)        {            if ((*it)->get_subflag())            {                std::cout<<(*it)->get_subject_status()<<"  "<<m_name.c_str()<<"  赶快努力工作"<<std::endl;            }        }           }private:    std::list<CSubject*> m_sublist;    std::string m_name;    int m_flag;};#endif//通知者基类#ifndef __OBSERVER_H#define __OBSERVER_H//存在互相依赖,为了方便直接注释掉//#include "Subject.h"#include <iostream>#include <string>class CObserver{public:    virtual void notify() = 0;    virtual std::string getname() = 0;    //virtual void add_sub(CSubject* ober)=0;};#endif//通知者员工A#ifndef __STAFFA_H#define __STAFFA_H#include <iostream>#include <list>#include "Observer.h"#include "Subject.h"class CStaffA:public CObserver{public:    CStaffA(std::string name)    {        m_name = name;    }    void add_sub(CSubject* ober)    {        m_sublist.push_back(ober);    }    void notify()    {        for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++)        {            if ((*it)->get_subflag())            {                std::cout<<(*it)->get_subject_status()<<"  "<<m_name.c_str()<<"  赶快努力工作"<<std::endl;            }        }    }    std::string getname()    {        return m_name;    }private:    std::string m_name;    std::list<CSubject*> m_sublist;};#endif//通知者员工B #ifndef __STAFFB_H#define __STAFFB_H#include <iostream>#include <list>#include "Observer.h"#include "Subject.h"class CStaffB:public CObserver{public:    CStaffB(std::string name)    {        m_name = name;    }    void add_sub(CSubject* ober)    {        m_sublist.push_back(ober);    }    void notify()    {        for (std::list<CSubject*>::iterator it=m_sublist.begin(); it!=m_sublist.end(); it++)        {            if ((*it)->get_subflag())            {                std::cout<<(*it)->get_subject_status()<<"  "<<m_name.c_str()<<"  赶快努力工作"<<std::endl;            }        }    }    std::string getname()    {        return m_name;    }private:    std::string m_name;    std::list<CSubject*> m_sublist;};#endif//client调用#include <iostream>#include "Subject.h"#include "BigBoss.h"#include "Boss.h"#include "StaffA.h"#include "StaffB.h"// 这个代码调了好久,在list容器中存放的为指针,那么在使用的时候即为双重指针,我又搞忘了//这个代码很有意思,值得好好分析//采用文本编辑的时候,确实容易出现很多低级错误,拼写等int main(void){    CBigBoss* bigboss = new CBigBoss("zhangpg");    CBoss* leader = new CBoss("zhangkuan");    CStaffA* staffa = new CStaffA("xiaoli");    CStaffB* staffb = new CStaffB("Lucy");    staffa->add_sub(bigboss);    staffa->add_sub(leader);    staffb->add_sub(bigboss);    staffb->add_sub(leader);        bigboss->add(leader);    bigboss->add(staffa);    bigboss->add(staffb);    leader->add(staffa);    leader->add(staffb);    leader->add_sub(bigboss);    std::cout<<"this is bigboss action."<<std::endl;    bigboss->action();    std::cout<<"\n\nthis is leader action"<<std::endl;    leader->action();    return 0;}
0 0