设计模式(C++实现)(十二)——观察者模式

示例问题:

当一个对象发生改变,需要同时改变其他很多对象的时候,如何让着对个对象同时监听一个对象?

分析:

将所有待改变的对象抽象一个通用的类和方法,作为基类的观察者。一个对象改变的时候去通知所有的观察者(执行基类观察者的抽象方法)

解决方案:

Observer.h

该文件实现了观察者的基类CBaseObserver(封装了通用的执行方法),通知者的基类CBaseNotifier(能够增删观察者,并通知所有管理的观察者执行动作)。观察者具体的类CConcreteObserverA(继承CBaseObserver,执行具体的执行方法),观察者具体的类CConcreteObserverB(继承CBaseObserver,执行具体的执行方法)。执行通知者CBaseNotifier的Notify方法时即可通知所有的观察者执行动作。应用了“依赖倒转原则”,让观察者和通知者的依赖关系在基类中实现,即依赖于抽象,而不是依赖于具体。

#pragma once

#include <list>
#include <iostream>
#include <string>

class CBaseObserver
{
public:
	CBaseObserver()
	{

	}
	
	virtual ~CBaseObserver()
	{

	}

	virtual void Action()
	{

	}
};

class CBaseNotifier
{
public:
	CBaseNotifier()
	{

	}

	virtual ~CBaseNotifier()
	{

	}

	void AddObserver(CBaseObserver* pObserver)
	{
		m_listObserver.push_back(pObserver);
	}

	void DelObserver(CBaseObserver* pObserver)
	{
		m_listObserver.remove(pObserver);
	}

	void Notify()
	{
		for (auto pObserver : m_listObserver)
		{
			if (nullptr != pObserver)
			{
				pObserver->Action();
			}
		}
	}

private:
	std::list<CBaseObserver*> m_listObserver;//观察者列表
};

class CConcreteObserverA : public CBaseObserver
{
public:
	CConcreteObserverA(std::string strName)
	: m_strName(strName)
	{

	}

	virtual ~CConcreteObserverA()
	{

	}

	void Action()
	{
		std::cout << "A类观察者" << m_strName << "执行动作" << std::endl;
	}

private:
	std::string m_strName;
};

class CConcreteObserverB : public CBaseObserver
{
public:
	CConcreteObserverB(std::string strName)
	: m_strName(strName)
	{

	}

	virtual ~CConcreteObserverB()
	{

	}

	void Action()
	{
		std::cout << "B类观察者" << m_strName << "执行动作" << std::endl;
	}

private:
	std::string m_strName;
};

class CConcreteNotifier : public CBaseNotifier
{
public:
	CConcreteNotifier()
	{

	}

	virtual ~CConcreteNotifier()
	{

	}

private:
	int m_iValue;
};


main.cpp

// main.cpp : Defines the entry point for the console application.
//

#include "Observer.h"


int main()
{
	CConcreteObserverA* pObserver1 = new(std::nothrow) CConcreteObserverA("观察者1号");
	CConcreteObserverA* pObserver2 = new(std::nothrow) CConcreteObserverA("观察者2号");
	CConcreteObserverB* pObserver3 = new(std::nothrow) CConcreteObserverB("观察者3号");

	CConcreteNotifier ConcreteNotifier;
	ConcreteNotifier.AddObserver(pObserver1);
	ConcreteNotifier.AddObserver(pObserver2);
	ConcreteNotifier.AddObserver(pObserver3);

	ConcreteNotifier.Notify();

	if (nullptr != pObserver1)
	{
		delete pObserver1;
		pObserver1 = nullptr;
	}

	if (nullptr != pObserver2)
	{
		delete pObserver2;
		pObserver2 = nullptr;
	}

	if (nullptr != pObserver3)
	{
		delete pObserver3;
		pObserver3 = nullptr;
	}

	system("pause");
    return 0;
}

运行结果:

观察者模式的使用:

观察者模式(又叫做发布—订阅(Publish/Subscribe)模式),定义了一种一对多的依赖关系。让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,二不是依赖于具体。从而使得各自的变化都不会影响另外一边的变化(很好的体现了依赖倒转原则)。

何时使用观察者模式:

当一个对象的改变需要同时改变其他对象,且他不知道具体有多少对象有待改变时,应该考虑使用观察者模式。

 

返回目录:设计模式(C++实现)(总)

上一篇:设计模式(C++实现)(十一)——建造者模式

下一篇:设计模式(C++实现)(十三)——抽象工厂模式

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值