观察者模式(Observer)

设计模式系列

Observer 观察者模式——对象行为模式

1.意图

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

 

2.适用性

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

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。

 

3.结构

4.参与者

  • Subject (目标)

—— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。一提供注册和删除观察者对象的接口。

  • Observer (观察者)

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

—— 将有关状态存入各ConcreteObserver对象。

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

  • ConcreteObserver (具体观察者)

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

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

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

 

5.效果

优点:

1)可以实现表示层和数据逻辑层的分离,在观察目标和观察者之间建立一个抽象的耦合

2)支持广播通信,简化了一对多系统设计的难度 符合开闭原则

3)增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便

缺点:

1)将所有的观察者都通知到会花费很多时间

2)如果存在循环依赖时可能导致系统崩溃,没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化

 

6.案例

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

///抽象一个Subject主题
///观察者
class Observer 
{
public:
	virtual void update(string m_Temp, string m_Humi) = 0;
protected:
	Observer() {}
};

class Subject 
{
public:
	virtual void registerObserver(Observer* pObj) = 0;
	virtual void removeObserver(Observer* pObj) = 0;
	virtual void noitfyObserver() = 0;
protected:
	Subject() {}
};

class WeatherData :public Subject 
{
public:
	WeatherData(string Temp, string Humi) : m_Temp(Temp), m_Humi(Humi) {}
	void registerObserver(Observer* pObj) { m_observers.push_back(pObj); }
	void removeObserver(Observer* pObj) 
	{
		auto iter = find(m_observers.begin(), m_observers.end(), pObj);
		if (iter != m_observers.end()) { m_observers.erase(iter); }
	}
	void noitfyObserver() 
	{
		//逐个遍历调用Observer的update方法
		for (vector<Observer*>::iterator iter = m_observers.begin(); iter != m_observers.end(); iter++) 
		{
			(*iter)->update(m_Temp, m_Humi);
		}
	}

	void setData(string Temp, string Humi) 
	{
		m_Temp = Temp;
		m_Humi = Humi;
		noitfyObserver();
	}
private:
	vector<Observer*> m_observers;
	string m_Temp;//温度
	string m_Humi;//湿度
};

//CocreteObserver
class PCDisplay :public Observer 
{
public:
	void update(string m_Temp, string m_Humi) 
	{
		cout << "我是PC端的显示GUI,当前的温度为" << m_Temp << "湿度为" << m_Humi << endl;
	}

	PCDisplay(WeatherData* pWeatherData) 
	{
		m_pWeatherData = pWeatherData;
		m_pWeatherData->registerObserver(this);
	}
private:
	WeatherData* m_pWeatherData;
};

class MobileDisplay :public Observer 
{
public:
	void update(string m_Temp, string m_Humi) 
	{
		cout << "我是Mobile端的显示GUI,当前的温度为" << m_Temp << "湿度为" << m_Humi << endl;
	}

	MobileDisplay(WeatherData* pWeatherData) 
	{
		m_pWeatherData = pWeatherData;
		m_pWeatherData->registerObserver(this);
	}

private:
	WeatherData* m_pWeatherData;
};

int main(void) 
{
	WeatherData* pWD = new WeatherData("22C", "65%");
	PCDisplay* pPCDisplay = new PCDisplay(pWD);
	MobileDisplay* pMobile = new MobileDisplay(pWD);

	pWD->setData("38C", "55%");
	pWD->removeObserver(pMobile);
	pWD->setData("31", "44%");

	system("pause");
	return 0;
}

设计模式系列 https://blog.csdn.net/nie2314550441/article/details/105849726

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值