首页 > 其他分享 >观察者模式

观察者模式

时间:2023-11-26 21:55:29浏览次数:28  
标签:void 观察者 模式 observers ObserverInterface public

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

标签:void,观察者,模式,observers,ObserverInterface,public
From: https://www.cnblogs.com/spacerunnerZ/p/17858035.html

相关文章

  • Linux桥接模式无网络的坑
    Linux虚拟机是VMware装的CentOS764位,从NAT模式(网络正常)改到了桥接模式,就是上不去网,排查如下:0.更改乔迁模式: 1.输入命令:vim/etc/sysconfig/network-scripts/ifcfg-ens33 发现ONBOOT是yes没问题。2.曾经将桥接模式的自动改成Inter开头的那个,无效 3.死......
  • 企业集成模式-第十章
    十、消息传递端点10.1引言1)发送和接收模式某些端点模式即适用于发送者,也适用于接收者。它们通常涉及如何把应用与消息传递系统联系起来。封装消息传递代码:大多数应用的代码在编写时没有考虑消息传递问题。当应用需要与其他程序集成时,应该由一个很瘦的代码层实现应用的集成功......
  • SQL Server使用Windows身份验证模式安装后,重新设置SA密码
    首次安装SQLServer使用Windows身份验证模式安装后,要重新设置自带用户SA的密码(1)右键数据库--》属性(2)安全性-->勾选“SQLserver和Windows身份认证模式(S)”(3)数据库下“安全性”-->“登录名”-->“sa”-->"属性"(4)直接输入需要设置的密码(5)给sa用户设置权限,在“服务器角色”设置为public......
  • 实验10:组合模式
    实验10:组合模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解组合模式的动机,掌握该模式的结构;2、能够利用组合模式解决实际问题。 [实验任务一]:组合模式用透明组合模式实现教材中的“文件夹浏览”这个例子。实验要求:1. 类图如下  2. 源代码以及......
  • 实验9:桥接模式
    实验9:桥接模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解桥接模式的动机,掌握该模式的结构;2、能够利用桥接模式解决实际问题。 [实验任务一]:两个维度的桥接模式用桥接模式实现在路上开车这个问题,其中,车可以是car或bus,路可以是水泥路或沥青路。实验要求......
  • Centos7 系统 /etc/fstab配置文件中文件系统类型错误导致进入紧急模式如何解决
    在格式化分区是我选择的ext4文件格式对分区sdc2进行了格式化,但是在写入配置文件是选择的文件格式是xfs,这导致了我的虚拟机进入系统时直接进入了紧急模式输入root密码进行维护,可以发现出现了命令窗,由于知道错误原因,所以可以直接从根源入手打开配置文件vim/etc/fstab我对设备......
  • 实验6:原型模式
    实验6:原型模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解原型模式的动机,掌握该模式的结构;2、能够利用原型模式解决实际问题。 [实验任务一]:向量的原型用C++完成数学中向量的封装,其中,用指针和动态申请支持向量长度的改变,使用浅克隆和深克隆复制向量类,比......
  • 实验7:单例模式
    实验7:单例模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解单例模式的动机,掌握该模式的结构;2、能够利用单列模式解决实际问题。 [实验任务一]:学号的单一仿照课堂的身份证的例子,实现每个同学仅有一个学号这一问题。实验要求:1. 画出对应的类图;  ......
  • 实验8:适配器模式
    实验8:适配器模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解适配器模式的动机,掌握该模式的结构;2、能够利用适配器模式解决实际问题。 [实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。实验要求:1. 对应的类图如下;  ......
  • 设计模式相关复习短篇
    1--设计模式基本概念设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码,让代码更容易被他人理解、提高代码的可靠性。2--设计模式基本要素模式名称,问题,解决方案,效果模式别名,模式的分类,模式的适用性,模式角色,模式实例,模......