观察者模式(OBSERVER)c++

大话设计模式中的观察者模式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;

};


//同事类继承Observer
class 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值