示例问题:
当一个对象发生改变,需要同时改变其他很多对象的时候,如何让着对个对象同时监听一个对象?
分析:
将所有待改变的对象抽象一个通用的类和方法,作为基类的观察者。一个对象改变的时候去通知所有的观察者(执行基类观察者的抽象方法)
解决方案:
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++实现)(总)