观察者模式

发布时间 2023-11-26 21:50:55作者: blogzzt

1 模式动机

建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

观察者模式的核心思想是 1对多

 

2 模式定义

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式是一种对象行为型模式。

3 模式结构

  • Subject: 目标
  • ConcreteSubject: 具体目标
  • Observer: 观察者
  • ConcreteObserver: 具体观察者

../_images/Obeserver.jpg

 

4 例子

以一个打工人A为例,A下班的时候会告诉孩子和妈妈,A开车要往回走了

  • 孩子妈收到消息后开始做饭
  • 孩子收到消息后,就赶紧收起手机,怕挨揍

4.1 未重构前

#include <iostream>
class Son{
public:
    void DoSomething(){
        std::cout<<"爸爸回来了,赶紧去写作业"<<std::endl;
    }
};

class Wife{
public:
    void DoSomething(){
        std::cout<<"老公回来了,去做饭"<<std::endl;
    }
};

class Me{
public:
    void Gohome(){
        wife.DoSomething();
        son.DoSomething();
    }
private:
    Wife wife;
    Son son;
};

int main(){
    Me me;
    me.Gohome();
    return 0;
}

这样写的不足如下:

如果关心我的人变多了,比如我又加了我老妈、老爸 ,这时候我们不得不去修改Me的类。假如关心我的人有1000人,那这时候我们该怎么办

class Me{
public:
    void Gohome(){
        wife.DoSomething();
        son.DoSomething();
        mom.DoSomething();
        ba.DoSomething();
    }
private:
    Wife wife;
    Son son;
    Mother mom;
    Father ba;
};

 

4.2 重构后

观察者接口

class ObserverInterface{
public:
    virtual void dosomething()=0;
    virtual ~ObserverInterface(){}
};

被观察者(目标)接口

class SubjectInterface{
public:
    virtual void Add(ObserverInterface* obr)=0;
    virtual void Remove(ObserverInterface* obr)=0;
    virtual void Notify()=0;

    virtual ~SubjectInterface(){}
};

我自己(ConcreteSubject):

class Me:public SubjectInterface{
public:
    void Add(ObserverInterface* obr) override{
        observers.push_back(obr);
    }

    void Remove(ObserverInterface* obr) override{
        auto pos=std::find(observers.begin(),observers.end(),obr);
        if(pos!=observers.end()){
            observers.erase(pos);
        }
    }

    void Notify() override{
        for(const auto& obs:observers){
            obs->dosomething();
        }
    }

private:
    std::vector<ObserverInterface*> observers;
};

孩子妈(ConcreteObserver):

class Wife:public ObserverInterface{
public:
    void dosomething() override{
        std::cout<<"老公快回来了,开始做饭"<<std::endl;
    }
};

孩子(ConcreteObserver):

class Son:public  ObserverInterface{
public:
    void dosomething() override {
        std::cout<<"爸爸快回来了,不能玩游戏了"<<std::endl;
    }
};

main函数

int main(){
    Me me;
    ObserverInterface* wife=new Wife;
    ObserverInterface* son=new Son;
    me.Add(wife);
    me.Add(son);

    //下班了 发消息
    me.Notify();

    delete wife;
    delete son;
}

这样的好处是:

  • 再增加新的观察者,我们就不用修改Me的类了,只需要添加到vector中就可以

不足是:

  • 需要自己做内存管理去 delete,可以改用为智能指针。

 

 

参考链接:https://design-patterns.readthedocs.io/zh-cn/latest/behavioral_patterns/observer.html

https://zhuanlan.zhihu.com/p/119308881