[设计模式]观察者模式(Observer)

1.意图

       定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

2.动机

       将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使得各类紧密耦合,因为这样降低了它们的可重用性。

       举个例子,一个表格对象和一个柱状图对象还有一个饼图对象,可以描述同一个数据对象,所以当数据对象改变的时候,以上这三个对象也应当同时更新。

3.结构与参与者


4.效果

       观察者模式允许你独立地改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者,反之亦然。它也使你可以在不改动目标和其他的观察者的前提下增加观察者。

1)目标和观察者之间的抽象耦合

       因为目标和观察者不是紧密耦合的,它们可以属于一个系统中的不同抽象层次。

2)支持广播通信

3)意外的更新(缺)

       因为一个观察者并不知道其他观察者的存在,它可能对改变目标的最终代价一无所知。在目标上一个看似无害的操作可能会引起一系列对观察者以及依赖于这些观察者的那些对象的更新。此外,如果依赖准则的定义或维护不当,常常会引起错误的更新,这种错误通常很难捕捉。

       简单的更新协议不提供具体细节说明目标中什么被改变了,这就使得上述问题更加严重。

5.实现

6.代码示例


例:
#include <string>
#include <iostream>
#include <vector>
using namespace std;

class SecretaryBase;
//抽象观察者
class CObserverBase
{
protected:
	string name;
	SecretaryBase* sub;
public:
	CObserverBase(string strname,SecretaryBase* strsub)
	{
		name=strname;
		sub=strsub;
	}
	virtual void Update()=0;
};
//具体的观察者,看股票的
class StockObserver : public CObserverBase
{
public:
	StockObserver(string strname,SecretaryBase* strsub) : CObserverBase(strname,strsub)
	{
	}
	virtual void Update();
};

//具体观察者,看NBA的
class NBAObserver : public CObserverBase
{
public:
	NBAObserver(string strname,SecretaryBase* strsub) : CObserverBase(strname,strsub){}
	virtual void Update();
};


//抽象通知者
class SecretaryBase
{
public:
	string action;
	vector<CObserverBase*> observers;
public:
	virtual void Attach(CObserverBase* observer)=0;
	virtual void Notify()=0;
};

//具体通知者
class Secretary :public SecretaryBase
{
public:
	void Attach(CObserverBase* ob)
	{
		observers.push_back(ob);
	}
	void Notify()
	{
        vector<CObserverBase*>::iterator p = observers.begin();
		while (p!=observers.end())
		{
			(*p)->Update();
			p++;
		}
	}
};

void StockObserver::Update()
{
	cout<<name<<":"<<sub->action<<",不要玩股票了,要开始工作了"<<endl;
}
void NBAObserver::Update()
{
	cout<<name<<":"<<sub->action<<",不要看NBA了,老板来了"<<endl;
}


客户端:
int main()
{
    SecretaryBase *p=new Secretary();  //创建观察者
	
	//被观察的对象
	CObserverBase *s1= new NBAObserver("小李",p);
	CObserverBase *s2 = new StockObserver("小赵",p);
    //加入观察队列
	p->Attach(s1);
	p->Attach(s2);
    //事件
	p->action="老板来了";
	//通知
	p->Notify();

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值