1、观察者模式知识点
1、定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖它的对象都得到通知并自动更新。
2、动机
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
3、使用条件
在以下任一情况下可以使用观察者模式 :
• 当一个抽象模型有两个方面 , 其中一个方面依赖于另一方面。将这二者封装在独立的对
象中以使它们可以各自独立地改变和复用。
• 当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
• 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦合的。
4、结构
5、使用范围和优缺点
观察者模式允许你独立的改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者, 反之亦然。它也使你可以在不改动目标和其他的观察者的前提下增加观察者。
下面是观察者模式其它一些优缺点 :
(1)目标和观察者间的抽象耦合 一个目标所知道的仅仅是它有一系列观察者 , 每个都符合抽象的观察者类的简单接口。目标不知道任何一个观察者属于哪一个具体的类。这样目标和观察者之间的耦合是抽象的和最小的。因为目标和观察者不是紧密耦合的 , 它们可以属于一个系统中的不同抽象层次。一个处于较低层次的目标对象可与一个处于较高层次的观察者通信并通知它 , 这样就保持了系统层次的完整。如果目标和观察者混在一块 , 那么得到的对象要么横贯两个层次 (违反了层次性 ), 要么必须放在这两层的某一层中 (这可能会损害层次抽象 )。
(2)支持广播通信 不像通常的请求, 目标发送的通知不需指定它的接收者。通知被自动广播给所有已向该目标对象登记的有关对象。目标对象并不关心到底有多少对象对自己感兴趣 ;它唯一的责任就是通知它的各观察者。这给了你在任何时刻增加和删除观察者的自由。处理还是忽略一个通知取决于观察者。
(3)意外的更新 因为一个观察者并不知道其它观察者的存在 , 它可能对改变目标的最终代价一无所知。在目标上一个看似无害的的操作可能会引起一系列对观察者以及依赖于这些观察者的那些对象的更新。此外 , 如果依赖准则的定义或维护不当,常常会引起错误的更新 , 这种错误通常很难捕捉。
2、示例代码
示例代码如下:
/*************************************************************************
> File : observer_mode.cpp
> Author : 小和尚念经敲木鱼
> Email : null
> Time : Tue 03 Aug 2021 05:27:41 PM CST
*************************************************************************/
#include <iostream>
#include <list>
using namespace std;
/************************************************************************
* 文件说明
* 观察者模式示例
*************************************************************************/
class Ilistenner
{
public:
virtual void onMessageHandle(int msg) = 0;
};
class INotifier
{
public:
virtual void RegisterListenner(Ilistenner * listenner) = 0;
virtual void unRegisterListenner(Ilistenner * listenner) = 0;
virtual void notify() = 0;
};
class NotifierManager : public INotifier
{
public:
void RegisterListenner(Ilistenner * listenner)
{
mListListenner.push_back(listenner);
}
void unRegisterListenner(Ilistenner * listenner)
{
list<Ilistenner*>::iterator ite;
for (ite = mListListenner.begin(); ite != mListListenner.end(); ite++)
{
if (*ite == listenner) {
mListListenner.remove(listenner);
break;
}
}
}
void notify()
{
list<Ilistenner*>::iterator ite;
for (ite = mListListenner.begin(); ite != mListListenner.end(); ite++)
{
(*ite)->onMessageHandle(mMsgValue);
}
}
void setValue(int value)
{
mMsgValue = value;
notify();
}
private:
list<Ilistenner *> mListListenner;
int mMsgValue;
};
class testListenner1 : public Ilistenner
{
public:
void onMessageHandle(int msg)
{
std::cout << "[testLisenner1] msg = " << msg << std::endl;
}
};
class testListenner2 : public Ilistenner
{
public:
void onMessageHandle(int msg)
{
std::cout << "[testLisenner2] msg = " << msg << std::endl;
}
};
int main(int argc,char * argv[])
{
class NotifierManager manager;
class testListenner1 test1;
class testListenner2 test2;
manager.RegisterListenner(&test1);
manager.RegisterListenner(&test2);
manager.setValue(1);
manager.setValue(2);
std::cout << "########################" << std::endl;
manager.unRegisterListenner(&test2);
manager.setValue(1);
manager.setValue(2);
return 0;
}
//out
//[testLisenner1] msg = 1
//[testLisenner2] msg = 1
//[testLisenner1] msg = 2
//[testLisenner2] msg = 2
//########################
//[testLisenner1] msg = 1
//[testLisenner1] msg = 2
3、总结
观察者模式,简答来说就是一个管理对象,一旦发生变化的时候,就通知管理对象管理的对象链表。