【设计模式】08 观察者模式

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

观察者模式解决什么问题:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

观察者模式的使用场合

在以下任一情况下都可以使用观察者模式:

(1)当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
(2)一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度;
(3)当一个对象必须通知其它对象,而它又不能假定其它对象是谁;也就是说,你不希望这些对象是紧密耦合的。

观察者模式的结构和实现

结构

观察者模式中包含以下角色

【1】Subject(目标)

目标知道它的观察者。可以有任意多个观察者观察同一个目标;

提供注册和删除观察者对象的接口。

【2】Observer(观察者)

为那些在目标发生改变时需获得通知的对象定义一个更新接口。

【3】ConcreteSubject(具体目标)

将有关状态存入各ConcreteObserver对象;

当它的状态发生改变时,向它的各个观察者发出通知。

【4】ConcreteObserver(具体观察者)

维护一个指向ConcreteSubject对象的引用;

存储有关状态,这些状态应与目标的状态保持一致;

实现Observer的更新接口以使自身状态与目标的状态保持一致。

实现

当具体目标ConcreteSubject 发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。

在得到一个具体目标的改变通知后,具体观察者对象ConcreteObserver可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。

原文链接:https://blog.csdn.net/weixin_39411321/article/details/89789720

案例:

五个英雄在打BOSS时,如果BOSS被打死了,"BOSS"对象则会向"英雄"反馈信息;而在这途中,如果某一个英雄被BOSS打死,则BOSS不会向它反馈信息;

这里的Observer(观察者)就是"英雄",而Subject(目标)是"BOSS"。在将其抽象出来。

而在Subject(目标)中应该提供三个方法:增加观察者、删除观察者、通知所有观察者。

#include <iostream>
#include <list>
using namespace std;

//抽象的英雄  抽样的观察者
class AbstractHero
{
public:
	virtual void update() = 0;      //更新状态方法
};

/*****************************************************************************************/
//英雄A          具体的观察者
class HeroA:public AbstractHero
{
public:
	HeroA()
	{
		cout << "英雄A正在打BOSS......" << endl;
	}

	virtual void update()
	{
		cout << "英雄A停止打BOSS,进入待机状态......" << endl;
	}
};

//英雄B
class HeroB :public AbstractHero
{
public:
	HeroB()
	{
		cout << "英雄B正在打BOSS......" << endl;
	}

	virtual void update()
	{
		cout << "英雄B停止打BOSS,进入待机状态......" << endl;
	}
};


//英雄C
class HeroC :public AbstractHero
{
public:
	HeroC()
	{
		cout << "英雄C正在打BOSS......" << endl;
	}

	virtual void update()
	{
		cout << "英雄C停止打BOSS,进入待机状态......" << endl;
	}
};


//英雄D
class HeroD :public AbstractHero
{
public:
	HeroD()
	{
		cout << "英雄D正在打BOSS......" << endl;
	}

	virtual void update()
	{
		cout << "英雄D停止打BOSS,进入待机状态......" << endl;
	}
};

//英雄E
class HeroE :public AbstractHero
{
public:
	HeroE()
	{
		cout << "英雄E正在打BOSS......" << endl;
	}

	virtual void update()
	{
		cout << "英雄E停止打BOSS,进入待机状态......" << endl;
	}
};
/***********************************************************************************************/
//抽样的观察目标
class AbstractBoss
{
public:
	//增加观察者
	virtual void addHero(AbstractHero* hero) = 0;
	//删除观察者
	virtual void deleteHero(AbstractHero* hero) = 0;
	//通知所有观察者
	virtual void notify() = 0;
};

//具体放入观察者
class BossA :public AbstractBoss
{
public:
	//增加观察者
	virtual void addHero(AbstractHero* hero)
	{
		pHeroList.push_back(hero);
	}
	//删除观察者
	virtual void deleteHero(AbstractHero* hero)
	{
		pHeroList.remove(hero);
	}
	//通知所有观察者
	virtual void notify()
	{
		for (list<AbstractHero*>::iterator it = pHeroList.begin(); it != pHeroList.end(); it++)
		{
			//通知
			(*it)->update(); 
		}
	}
	//析构函数
	//如何析构呢?
	~BossA()
	{

	}

private:
	list<AbstractHero*> pHeroList;
};

void test01()
{
	//创建观察者
	AbstractHero* heroA = new HeroA;
	AbstractHero* heroB = new HeroB;
	AbstractHero* heroC = new HeroC;
	AbstractHero* heroD = new HeroD;
	AbstractHero* heroE = new HeroE;

	//创建观察目标
	AbstractBoss* bossA = new BossA;
	//加入
	bossA->addHero(heroA);
	bossA->addHero(heroB);
	bossA->addHero(heroC); 
	bossA->addHero(heroD);
	bossA->addHero(heroE);

	cout << "heroC阵亡......" << endl;
	bossA->deleteHero(heroC);      
	
	cout << "BossA阵亡,通知其他英雄停止攻击......" << endl;
	bossA->notify();

	delete bossA;
	delete heroA;
	delete heroB;
	delete heroC;
	delete heroD;
	delete heroE;

}

int main(int argc, int* argv[])
{
	test01();
	system("pause");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值