观察者模式(OBSERVER)c++

来源:互联网 发布:天猫跟淘宝有啥区别 编辑:程序博客网 时间:2024/05/22 17:15

大话设计模式中的观察者模式c++版本

/* * observer.cpp * *  Created on: Jul 31, 2017 *      Author: clh01s@163.com *      观察者模式: *      定义对象间的一种一对多的依赖关系, *      当一个对象的状态发生改变时,所有依 *      赖于它的对象都得到通知并被自动更新 *      . */#include <iostream>#include <string>#include <vector>using namespace std;//前置声明class Secretary;class Subject;//抽象观察者class Observer{public:    //初始化保护变量分别是被通知对象和通知对象    Observer(string name,Subject *sub):name_(name),sub_(sub){}    virtual ~Observer(){}    //更新虚函数    virtual void Update()=0;protected:    string name_;    //私有虚基类指针变量保证低耦合    Subject *sub_;};//抽象通知者class Subject{public:    virtual ~Subject(){}    virtual void Attach(Observer *observer) = 0;    virtual void Detach(Observer *observer) = 0;    virtual void Notify() = 0;    virtual void setAction(string action) = 0;    virtual string getAction() = 0;};//同事类继承Observerclass StockObserver:public Observer{public:    //带参构造函数,初始化两个私有变量一个名称,一个告知消息对象的指针用于获得该对象的告知事项    StockObserver(string name,Subject *sub):Observer(name,sub){}    void Update() override    {        cout<<sub_->getAction()<<name_<<"关闭视频继续工作"<<endl;    }};//前台秘书类class Secretary:public Subject{public:    //添加实例函数    void Attach(Observer *observer) override    {        _stock_vec.push_back(observer);    }    //删除实例函数    void Detach(Observer *observer) override    {        bool flage = false;        for(int i = 0;i < _stock_vec.size();++i)        {            if(observer == _stock_vec[i])            {                _stock_vec.erase(_stock_vec.begin()+i);                flage = true;            }        }        if(!flage)        {            std::cout<<"数据删除失败!!!"<<std::endl;        }    }    //设置前台告知事项    void setAction(string action) override    {        _action = action;    }    //获得前台告知的事项    string getAction() override    {        return _action;    }    //通知函数    void Notify() override    {        for(auto i:_stock_vec)        {            i->Update();        }    }private:    vector<Observer*> _stock_vec;    string _action;};//boss类和Secretary类功能一致用于体现不同对象产生不一样的结果class Boss:public Subject{public:    //添加实例函数    void Attach(Observer *observer) override    {        _stock_vec.push_back(observer);    }    //删除实例函数    void Detach(Observer *observer) override    {        bool flage = false;        for(int i = 0;i < _stock_vec.size();++i)        {            if(observer == _stock_vec[i])            {                _stock_vec.erase(_stock_vec.begin()+i);                flage = true;            }        }        if(!flage)        {            std::cout<<"数据删除失败!!!"<<std::endl;        }    }    //设置老板告知的事项    void setAction(string action) override    {        _action = action;    }    //获得老板告知的事项    string getAction() override    {        return _action;    }    //通知函数    void Notify() override    {        for(auto i:_stock_vec)        {            i->Update();        }    }private:    vector<Observer*> _stock_vec;    string _action;};int main(){    //前台    Secretary *xiaomei = new Secretary();    //老板    Boss *wang = new Boss();    //同事(前台通知)传入前台变量的指针    StockObserver *xiaohei = new StockObserver("小黑",xiaomei);    StockObserver *xiaoming = new StockObserver("小明",xiaomei);    //同事(老板通知)传入老板变量的指针    StockObserver *xiaohei2 = new StockObserver("小黑",wang);    StockObserver *xiaoming2 = new StockObserver("小明",wang);    //将同事加入通知列表    xiaomei->Attach(xiaohei);    xiaomei->Attach(xiaoming);    //设置通知事项    xiaomei->setAction("老板回来了!");    //通知同事    xiaomei->Notify();    cout<<"老板再次出现由老板通知"<<endl;    //将同事加入通知列表    wang->Attach(xiaohei2);    wang->Attach(xiaoming2);    //小黑没有听到老板的通知所以从通知列表中删除,然后会被发现没有在工作    wang->Detach(xiaohei2);    //老板通知    wang->setAction("我回来了!");    wang->Notify();    return 0;}

程序输出结果:
老板回来了!小黑关闭视频继续工作
老板回来了!小明关闭视频继续工作
老板再次出现由老板通知
我回来了!小明关闭视频继续工作

观察者模式适用于下面几种情况(摘录于《设计模式》):
1.当一个抽象模型有两个方面,其中一个方面依赖于另一个方面.将这二者封装在独立的对象中以使他们可以各自独立地改变和复用.
2.当一个对象的改变需要同时的改变其他对象,而不知道具体有多少对象有待改变.
3.当一个对象必须通知其他对象,而他又不能假定其他对象是谁.换言之你不希望这些对象是紧密耦合的.
观察者模式的优点:
1.目标和观察者间的抽象耦合 一个目标所知道的仅仅是它有一系列的观察者,每个都符合抽象的Observe类的简单接口.目标不知道任何一个观察者属于哪一个具体的类.这样目标和观察者之间的耦合是抽象的和最小的.
2.支持广播通信 目标发送的通知不需要指定他的接收者.通知被自动广播给所有登记的对象.目标也不关心有多少对象对自己感兴趣,他唯一的职责就是通知他的观察者.这给了你在任何时候增加和删除一个观察者的自由.处理或者忽略一个通知都只取决与观察者.
缺点:
意外的更新 因为一个观察者并不知道还有其他观察者的存在,他可能对改变目标的最终代价一无所知.一个看似无害的操作可能引起其他一系列的操作.另外如果依赖准则或者维护不当,常常会引起错误的更新而这些错误通常难以捕捉.

转载请注明源地址:http://blog.csdn.net/clh01s

原创粉丝点击