观察者模式是一个应用非常广的模式之一,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化,关注它的对象就会得到通知;这种交互也称为发布-订阅(publish-subscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者。
比如发布者(电子杂志),订阅者有张三、张四、张五,这几个人就是观察者。
发布者不关心有几个观察者,有更新时只管通知他们。
观察者收到更新通知,更新自己的状态。
观察者的一个实例 Model/View/Control( MVC) 结构在系统开发架构设计中有着很重要的地位和意义, MVC实现了业务逻辑和表示层的解耦。
MVC要求业务逻辑模型(Model)独立于于用户界面(view,视图,就是表示层),控制器(controller)接收用户输入并协调两者,MVC支持应用程序的功能模块化,
并具有以下优点:
(1)模型和视图组件的隔离,就可以实现多套用户界面,并且使这些界面能够重用公共的业务逻辑核心。
(2)避免了因为多份UI实现而构建多份重复的底层模型代码的问题。
(3)模型和视图代码的解耦简化了为了核心业务逻辑代码编写单元测试工作。
(4)组件的模块化允许核心逻辑开发者和GUI开发者并行工作,且互不影响。
Observer 模式要解决的问题为: 建立一个一( Subject)对多( Observer) 的依赖关系, 并且做到当“一” 变化的时候, 依赖这个“一”的多也能够同步改变。
观察者模式的实现
#include <iostream>
#include <vector>
#include <algorithm>
class Observer
{
public:
virtual void Update(int ) = 0;
};
class TureObserver1:public Observer
{
public:
void Update(int m)
{
m_state = m;
std::cout<<"TureObserver1 Update m = "<< m_state <<std::endl;
}
private:
int m_state;
};
class TureObserver2:public Observer
{
public:
void Update(int m)
{
m_state = m;
std::cout<<"TureObserver2 Update m = "<< m_state <<std::endl;
}
private:
int m_state;
};
class Subject
{
public:
Subject()
{
}
virtual ~Subject()
{
}
virtual void Register(Observer *pObserver)
{
ObserverList.push_back(pObserver);
}
virtual void UnRegister(Observer *pObserver)
{
std::vector < Observer *>::iterator iObserver = std::find(ObserverList.begin(), ObserverList.end(), pObserver);
if(iObserver != ObserverList.end())
{
ObserverList.erase(iObserver);
std::cout<<" unregister success !"<< std::endl;
}
else
{
std::cout<<" not find in list"<< std::endl;
}
}
virtual void Notify(int m)
{
std::vector < Observer *>::iterator iObserver = ObserverList.begin();
while(iObserver != ObserverList.end())
{
(*iObserver)->Update(m);
iObserver++;
}
}
private:
std::vector < Observer *> ObserverList;
};
class TrueSubject:public Subject
{
};
int main()
{
TrueSubject subject;
TureObserver2 Observer2;
TureObserver1 Observer1;
subject.Register(&Observer2);
subject.Register(&Observer1);
subject.Notify(5);
subject.UnRegister(&Observer2);
subject.UnRegister(&Observer1);
}
工作中遇到C语言中的观察者模式:
比如U盘的插入或者拔出,需要通知界面app,通知媒体管理模块,通知升级模块
这个时候U盘的现状就是个发布者。
界面app,媒体管理模块,升级模块就是观察者。
C语言的观察模式也是通过回调函数方式实现。界面app,媒体管理模块,升级模块分别往U盘模块注册回调函数。