设计模式-观察者模式

来源:互联网 发布:linux shell % 编辑:程序博客网 时间:2024/06/16 16:32

观察者模式,又叫发布-订阅(Publish/Subscribe)模式:定义了一种一对多的依赖关系,让多个观察对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知多个观察者对象,使他们能自动更新自己。

观察者模式一般用在:当一个对象的改变同时需要改变其他对象,而且它不知道具体有多少对象待改变时。
例子:公司通过秘书通知部分员工开会,秘书状态改变,员工将收到通知。当然老板也可以通知开会,所以就抽象出观察者类和通知者类
UML:
这里写图片描述

class Notifier;//抽象观察者class Observer {public:    Observer(string name, Notifier *notifer) :m_name(name), m_notifer(notifer) {}    virtual void Updata() = 0;protected:    string m_name;                                         //观察者名称    Notifier *m_notifer;                                  //观察者接受消息的通知者};//通知者class Notifier {public:    virtual void Attach(Observer *observer)   //增加观察者    {        m_obersvers.push_back(observer);    }    virtual void Detach(Observer *observer)  //减少观察者    {        m_obersvers.remove(observer);    }    virtual void Notify()                                   //发布通知    {        for (auto ob : m_obersvers)        {            ob->Updata();                                     //对每个观察者调用其更新函数        }    }    virtual void SetStatus(string status)    {        m_status = status;    }    virtual string GetStatus()     {        return m_status;    }private:    list<Observer*> m_obersvers;                    //观察者列表protected:    string m_status;};//员工,具体观察者class Staff :public Observer {public:    Staff(string name, Notifier *notifer) :Observer(name, notifer) {}    void Updata()                                               //获得更新状态    {        string status = m_notifer->GetStatus();        cout << m_name << " 收到: " << status << endl;    }};//秘书,具体通知者class Secretary :public Notifier{public:    Secretary(string name) :m_name(name) {}    void SetStatus(string status)    {        m_status =  m_name + "代表公司通知" + status;    }    string GetStatus()    {        return m_status;    }private:    string m_name;};int main(){    Notifier *secretary = new Secretary("秘书");    Staff *staff1 = new Staff("小张",secretary);    Staff *staff2 = new Staff("小余", secretary);    secretary->Attach(staff1);    secretary->Attach(staff2);    secretary->SetStatus("今天下午开会");    secretary->Notify();    system("pause");    return 0;}
1 0
原创粉丝点击