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