设计模式之观察者模式-别只观察,要行动!

一、观察者模式的概念

观察者模式属于行为模式, 它提供给关联对象一种同步通信的手段, 使某个对象与依赖它的对象之间保持状态同步;作用是当一个对象的状态发生变化时, 能够自动通知它的关联对象,自动刷新对象状态。

二、观察者模式使用场景

1、当对象间存在一种一对多的依赖关系时,每一个对象改变状态都会影响其它对象,所有依赖于它的对象都会得到通知。
2、一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

三、观察者模式构建方法

1、被观察者抽象类(Subject)

被观察的对象抽象类,定义被观察者的共同接口和方法,当被观察的状态发生变化时,需要通知队列中所有观察者对象。

2、被观察者具体类(ConcreteSubject)

被观察者的具体实现类,实现抽象类中定义的共同接口和方法,包含一些基本的属性状态和行为等。

3、观察者的抽象类(Observer)

观察者的抽象父类,给具体观察者类提供统一的共同接口和方法,当被观察者状态发生变化时,将通过一个回调函数通知对象。

4、观察者的具体类(ConcreteObserver)

观察者的具体类继承观察者的抽象类,用于实现观察者的抽象父类中的共同接口和方法,得到通知后完成一些具体的业务逻辑处理。

四、观察者模式的示例

// ObserverPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <vector>

#define DELETE_PTR(p) {if(p!=nullptr){delete (p); (p)=nullptr;}}

using namespace std;

class Staff;

// 被观察者抽象类
class Leader
{
public:
	virtual void addObserver(Staff *pStaff) {}
	virtual void notifyAll() {}
	virtual void setLeaderStatus(int status) {}
	virtual int getLeaderStatus() { return 0; }
};

// 观察者抽象类-员工
class Staff
{
public:
	virtual void updateStatus() {}
};

// 被观察者具体实现类-部门经理
class DepartManager : public Leader
{
public:
	void addObserver(Staff *pStaff)
	{
		m_staffVector.push_back(pStaff);
	}

	void notifyAll()
	{
		if (m_leaderStatus == 1)
		{
			cout << "------------部门经理回来了--------------" << endl;
		}
		else
		{
			cout << "------------部门经理出去了--------------" << endl;
		}
		
		for (auto iter : m_staffVector)
		{
			iter->updateStatus();
		}
	}

	// 设置领导的状态,1-在,0-不在
	void setLeaderStatus(int status)
	{
		m_leaderStatus = status;
	}

	int getLeaderStatus()
	{
		return m_leaderStatus;
	}

private:
	vector<Staff*> m_staffVector;
	int m_leaderStatus;
};

// 被观察者具体实现类-技术总监
class CTOManager : public Leader
{
public:
	void addObserver(Staff *pStaff)
	{
		m_staffVector.push_back(pStaff);
	}

	void notifyAll()
	{
		if (m_leaderStatus == 1)
		{
			cout << "------------技术总监回来了--------------" << endl;
		}
		else
		{
			cout << "------------技术总监出去了--------------" << endl;
		}
		for (auto iter : m_staffVector)
		{
			Staff *pStaff = iter;
			pStaff->updateStatus();
		}
	}

	// 设置领导的状态,1-在,0-不在
	void setLeaderStatus(int status)
	{
		m_leaderStatus = status;
	}

	int getLeaderStatus()
	{
		return m_leaderStatus;
	}

private:
	vector<Staff*> m_staffVector;
	int m_leaderStatus;
};



// 观察者具体类-玩游戏的员工
class PlayGameStaff : public Staff
{
public:
	PlayGameStaff(Leader *pLeader, string name)
	{
		m_pLeader = pLeader;
		m_nameStr = name;
	}

	void updateStatus()
	{
		if (m_pLeader->getLeaderStatus() == 1) // 领导来了
		{
			cout << m_nameStr << "停止玩游戏,开始工作。" << endl;
		}
		else
		{
			cout << m_nameStr << "停止工作,开始玩游戏。" << endl;
		}
	}

private:
	Leader *m_pLeader;
	string m_nameStr;
};

// 观察者具体类-看电影员工
class WatchMovieStaff : public Staff
{
public:
	WatchMovieStaff(Leader *pLeader, string name)
	{
		m_pLeader = pLeader;
		m_nameStr = name;
	}

	void updateStatus()
	{
		if (m_pLeader->getLeaderStatus() == 1) // 领导来了
		{
			cout << m_nameStr << "停止看电影,开始工作。" << endl;
		}
		else
		{
			cout << m_nameStr << "停止工作,开始看电影。" << endl;
		}
	}

private:
	Leader *m_pLeader;
	string m_nameStr;
};

int main()
{
	cout << "---------------------观察者模式------------------" << endl;
	Leader *pDepartManager = dynamic_cast<Leader*>(new DepartManager);
	pDepartManager->setLeaderStatus(1);

	Staff *pPlayGameStaff = dynamic_cast<Staff*>(new PlayGameStaff(pDepartManager,"ISmileLI"));
	Staff *pWatchMovieStaff = dynamic_cast<Staff*>(new WatchMovieStaff(pDepartManager, "Toby"));

	pDepartManager->addObserver(pPlayGameStaff);
	pDepartManager->addObserver(pWatchMovieStaff);

	pDepartManager->notifyAll();
	pDepartManager->setLeaderStatus(0);
	pDepartManager->notifyAll();

	DELETE_PTR(pPlayGameStaff);
	DELETE_PTR(pWatchMovieStaff);

	cout << "--------------部门经理走了,技术总监又过来了--------------" << endl;
	Leader *pCTOManager = dynamic_cast<Leader*>(new CTOManager);
	pCTOManager->setLeaderStatus(1);
	

	pPlayGameStaff = dynamic_cast<Staff*>(new PlayGameStaff(pCTOManager, "ISmileLI"));
	pWatchMovieStaff = dynamic_cast<Staff*>(new WatchMovieStaff(pCTOManager, "Toby"));

	pCTOManager->addObserver(pPlayGameStaff);
	pCTOManager->addObserver(pWatchMovieStaff);

	pCTOManager->notifyAll();

	DELETE_PTR(pPlayGameStaff);
	DELETE_PTR(pWatchMovieStaff);
	DELETE_PTR(pDepartManager);
	DELETE_PTR(pCTOManager);

    std::cout << "Hello World!\n";
	getchar();
}

运行结果:
在这里插入图片描述

五、观察者模式的优缺点

优点:

1、降低了被观察者与观察者之间的耦合关系,两者之间是抽象耦合关系。
2、被观察者与观察者之间建立了一套触发机制。

缺点:

1、当一个被观察者有很多的观察者的话,所有的观察者都通知到会花费很多时间。
2、当被观察者和观察者之间有循环依赖的话,有可能造成系统死循环。
3、观察者模式没有相应的机制让观察者知道被观察者是怎么发生变化的,而仅仅知道被观察者发生了变化。

能力有限,如有错误,多多指教。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值