1、定义
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
2、介绍
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
3、源码
类关系图:
思路:1、定义观察者、被观察者类接口。2、被观察添加观察者类,被观察者类执行某个动作,触发观察的相应动作,观察者进行相应响应。
3.1、头文件
IObservable.h
#pragma once
#include "IObserver.h"
#include <iostream>
using namespace std;
class IObservable
{
public:
IObservable(void)
{
}
virtual ~IObservable(void)
{
}
virtual void AddObserver(IObserver *pObserver) = 0;
virtual void DeleteObserver(IObserver *pObserver) = 0;
virtual void NotifyObservers(string context) = 0;
};
HanFeiziObservable.h
#pragma once
#include "iobservable.h"
#include "IObserver.h"
#include <vector>
using std::vector;
class CHanFeiziObservable :
public IObservable
{
public:
CHanFeiziObservable(void);
~CHanFeiziObservable(void);
void AddObserver(IObserver *pObserver);
void DeleteObserver(IObserver *pObserver);
void NotifyObservers(string context);
void HaveBreakfast();
void HaveFun();
private:
vector<IObserver*> m_observerList;
typedef vector<IObserver*>::const_iterator ObserverList_C_iterator;
};
IObserver.h
#pragma once
#include<iostream>
#include<vector>
using namespace std;
class IObserver
{
public:
IObserver(string _name)
{
this->m_name = _name;
}
virtual ~IObserver(void)
{
}
virtual void Update(string context) = 0;
virtual string GetName() = 0;//为c++单独增加的函数,用于删除时查找观察者。
protected:
string m_name;
};
LiSiObserver.h
#pragma once
#include "iobserver.h"
class CLiSiObserver :
public IObserver
{
public:
CLiSiObserver(void);
~CLiSiObserver(void);
void Update(string context);
string GetName();
private:
void ReportToQinShiHuang(string report);
};
ZhouSiObserver.h
#pragma once
#include "iobserver.h"
class CZhouSiObserver :
public IObserver
{
public:
CZhouSiObserver(void);
~CZhouSiObserver(void);
void Update(string context);
string GetName();
private:
void Cry(string report);
};
3.2、实现
HanFeiziObservable.cpp
#include "HanFeiziObservable.h"
#include <iostream>
using std::string;
using std::cout;
using std::endl;
CHanFeiziObservable::CHanFeiziObservable(void)
{
}
CHanFeiziObservable::~CHanFeiziObservable(void)
{
}
void CHanFeiziObservable::AddObserver( IObserver *pObserver )
{
m_observerList.push_back(pObserver);
}
void CHanFeiziObservable::DeleteObserver( IObserver *pObserver )
{
ObserverList_C_iterator it = m_observerList.begin();
for (; it != m_observerList.end(); it++)
{
string name = (*it)->GetName();
if (name.compare(pObserver->GetName()) == 0)
{
//找到了删除。
}
}
}
void CHanFeiziObservable::NotifyObservers( string context )
{
ObserverList_C_iterator it = m_observerList.begin();
for (; it != m_observerList.end(); it ++)
{
(*it)->Update(context);
}
}
void CHanFeiziObservable::HaveBreakfast()
{
cout << "韩非子:开始吃饭了..." << endl;
this->NotifyObservers("韩非子在吃饭");
}
void CHanFeiziObservable::HaveFun()
{
cout << "韩非子:开始娱乐了..." << endl;
this->NotifyObservers("韩非子在娱乐");
}
LiSiObserver.cpp
#include "LiSiObserver.h"
CLiSiObserver::CLiSiObserver(void) : IObserver("李斯")
{
}
CLiSiObserver::~CLiSiObserver(void)
{
}
void CLiSiObserver::Update(string context)
{
cout << "李斯:观察到韩非子活动,开始向老板汇报了..." << endl;
this->ReportToQinShiHuang(context);
cout << "李斯:汇报完毕,秦老板赏给他两个萝卜吃吃..." << endl;
}
void CLiSiObserver::ReportToQinShiHuang(string report)
{
cout << "李斯:报告,秦老板!韩非子有活动了--->" << report.c_str() << endl;
}
string CLiSiObserver::GetName()
{
return m_name;
}
ZhouSiObserver.cpp
#include "ZhouSiObserver.h"
CZhouSiObserver::CZhouSiObserver(void) : IObserver("周斯")
{
}
CZhouSiObserver::~CZhouSiObserver(void)
{
}
void CZhouSiObserver::Update( string context )
{
cout << "周斯:观察到韩非子活动,自己也开始活动了..." << endl;
this->Cry(context);
cout << "周斯:真真的哭列了..." << endl;
}
void CZhouSiObserver::Cry( string report )
{
cout << "周斯:为因" << report.c_str() << ", ————所以我悲伤呀!" << endl;
}
string CZhouSiObserver::GetName()
{
return m_name;
}
Observer.cpp
#include "HanFeiziObservable.h"
#include "LiSiObserver.h"
#include "ZhouSiObserver.h"
void DoNewNew()
{
//IObservable.h, HanfeiziObservable.h, IObserver.h, LiSiObserver.h
cout << "----------用更新的方法再试试----------" << endl;
IObserver *pLiSi = new CLiSiObserver();
IObserver *pZhouSi = new CZhouSiObserver();
CHanFeiziObservable *pHanFeiZi = new CHanFeiziObservable();
pHanFeiZi->AddObserver(pLiSi);
pHanFeiZi->AddObserver(pZhouSi);
pHanFeiZi->HaveBreakfast();
delete pLiSi;
pLiSi = NULL;
delete pHanFeiZi;
pHanFeiZi = NULL;
}
int main()
{
//更抽象的方式,想要观察韩非子的人多了去了,不可能只允许李斯观察。
DoNewNew();
system("pause");
return 0;
}
4、结果
参考文献:《菜鸟教程》 https://blog.csdn.net/phiall/article/details/52199659博客