C++设计模式笔记——观察者模式

概念

观察者模式又被称为发布-订阅模式(Publish-Subscribe)、模型-视图模式(Model-View)、源-监听器模式(Source-Listener)、从属者模式(Dependents)。

它属于行为型模式的一种。

观察者模式:定义对象之间一对多的依赖关系,使得一个对象的状态发生改变时,它的关联对象都得到通知并被自动更新。

一个对象状态改变时(目标对象Subject),所有依赖他的对象(观察者对象Observer)都得到通知并能够发生改变。

Subject(目标):是被观察的对象,目标中定义了一个观察者的集合,即一个目标可能会有多个观察者,通过attach()和detach()方法来增删观察者对象。目标声明了通知方法notify(),用于在自身状态发生改变时通知观察者。
ConcreteSubject(具体目标):具体目标实现了通知方法notify(),同时具体目标有记录自身状态的属性和成员方法;
Observer(观察者):观察者将对接收到的目标发生改变的通知做出自身的反应,抽象层声明了更新方法update();
ConcreteObserver(具体观察者): 实现了更新方法update(),具体观察者中维护了一个具体目标对象的引用(指针),用于存储目标的状态。


观察者模式是使用频率非常高的一个设计模式,特别是在UI更新上。凡是涉及一对多的对象交互场景,都可以使用观察者会模式。比如购物车,用户往购物车里添加一件商品,就会引起UI多方面的变化;各种编程语言的GUI事件处理的实现;所有的浏览器事件(mouseover,keypress等)都是使用观察者模式的例子。

代码

class Observer    // 抽象观察者
{
public:  
         virtual void update() = 0;
};
 

class ConcreteObserver:public Observer   // 具体观察者
{
public:
         void update(){
                      //  实现响应更新方法   具体操作
          }
};
 

class Subject    // 抽象目标
{
public: 
    void attach(Observer* obs){
             obsList.push_back(obs);
    }
    void detach(Observer* obs){
              obsList.remove(obs);
    }
    virtual void notify() = 0;

protected:
          list<Observer*>  obsList;    // 观察者列表
};
 
class ConcreteSubject :public Subject   // 具体目标
{
public:
    void notify(){
        // 遍历通知观察者对象
        for (int i = 0; i < obsList.size(); i++){
                  obsList[i]->update();
        }
    }
};
 
int main()
{
    Subject  *sub = new ConcreteSubject();
    Observer *obs = new ConcreteObserver();
    sub->attach(obs);
    sub->notify();
    return 0;
}

优点

观察者模式实现了稳定的消息更新和传递的机制,通过引入抽象层可以扩展不同的具体观察者角色;
支持广播通信,所有已注册的观察者都会得到消息更新的通知,简化了一对多设计的难度;
符合开闭原则,新增的观察者无需修改已有代码,在具体观察者ConcreteObserver与观察目标之间不存在关联关系的情况下,增加新的观察目标Subject很方便。

缺点

代码中观察者Observer和观察目标Subject相互引用,存在循环依赖,观察目标会触发二者循环调用,有引起系统崩溃的风险;
如果一个观察目标对象有很多直接和简介观察者,将所有的观察者都通知到会耗费大量时间。


适用环境

一个对象的改变会引起其他对象的改变,但并不知道是哪些对象会产生改变以及产生什么样的改变;
如果需要设计一个触发式的系统,可是使用观察者模式;如:广播通信、消息更新通知等场景。
 

猜你喜欢

转载自blog.csdn.net/panjunnn/article/details/109651712