在GOF的《设计模式:可复用面向对象软件的基础》一书中对观察者模式是这样定义的:定义对象的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化,关注它的对象就会得到通知;这种交互也成为发布-订阅(publish-subscribe)。
#include <iostream>
#include <string>
#include <list>
#include <memory>
using std::unique_ptr;
using std::list;
using std::string;
using std::cout;
using std::endl;
// 观察者基类
class Observer{
public:
// 获取状态更新
virtual void update(int status) = 0;
// 虚析构函数
virtual ~Observer(){};
};
class ConcreteObserverA:public Observer{
public:
ConcreteObserverA(const string name)
:_name(name)
{
// 构造函数
}
virtual void update(int status) override{
cout << "ConcreteObserverA name is : " << _name << " status:" << status << endl;
}
private:
string _name;
};
class ConcreteObserverB:public Observer{
public:
ConcreteObserverB(const string name)
:_name(name)
{
// 构造函数
}
virtual void update(int status) override{
cout << "ConcreteObserverB name is : " << _name << " status:" << status << endl;
}
private:
string _name;
};
// 主题的抽象基类,所有番剧的基类
class Subject{
public:
// 添加观察者
virtual void attach(Observer * pob) = 0;
// 删除观察者
virtual void detach(Observer * pob) = 0;
// 通知观察者
virtual void notify() = 0;
virtual ~Subject(){};
};
// 具体的主题,假设是具体的番剧
class ConcreteSubject:public Subject{
public:
virtual void attach(Observer * pob) override{
if(pob){
_listOb.push_back(pob);
}
}
virtual void detach(Observer * pob) override{
if(pob){
_listOb.remove(pob);
}
}
virtual void notify() override{
for(auto & ele:_listOb){
ele->update(_status); // 实现动态
}
}
void setstatus(int sta){
_status = sta;
}
int getstatus(){
return _status;
}
private:
// 存放观察者的数据结构
list<Observer *> _listOb;
// 状态
int _status;
};
void test(void){
unique_ptr<Observer> ob1(new ConcreteObserverA("tianming"));
unique_ptr<Observer> ob2(new ConcreteObserverB("lili"));
// 创建主题对象
unique_ptr<ConcreteSubject> csub(new ConcreteSubject());
// 将观察者添加到主题的数据结构中进行存储
csub->attach(ob1.get());
csub->attach(ob2.get());
// 当主题状态发生变更
csub->setstatus(888);
// 马上发通知
csub->notify();
cout << endl;
// 当某个观察者不再关注该番剧
csub->detach(ob2.get());
// 再次变化
csub->setstatus(999);
// 立马通知
csub->notify();
}
int main(int argc, char * argv[]){
test();
return 0;
}
优点:
观察者和被观察者是抽象耦合的;
建立一套触发机制。
缺点:
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃;
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。