设计模式学习(十一) 观察者模式


这是个人学习编程模式的系列学习笔记第十一篇。
采用Qt Creator进行编写,但尽量采用C++基础语法。
观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时 , 所有依赖于它的对象
都得到通知并被自动更新。观察者模式又叫:依赖(Dependents)或发布-订阅模式(Publish-Subscribe)。
个人觉得发布-订阅模式最容易理解这个模式的含义。
一个对象作为发布者,多个对象作为订阅者,在发布者有状态变化的时候,会通知到全部的订阅者。最容易理解的是,一个人写了博客,有多个订阅者,如果博客更新,会通知全部的订阅者。
观察者模式主要用于:有两类对象关系密切,但有不希望两类对象紧耦合,通过抽象对象之间的接口实现发布对象状态的变化能通知到全部订阅对象。
观察者模式可以采用推模式和拉模式进行通知广播。推模式提供给观察者全部所需的信息,拉模式提供给观察者最小需要的信息,由订阅者向发布者询问更多需要的细节。
后期发展的委托技术是观察者模式的进一步升级。能实现对不同接口的通知(接口的参数需要相同)。

场景描述

假设要设计一个对外接收指令的接口,各种指令对应不同的类来处理,可能是多个,也可能是1个。接收到这个指令的类根据自己的情况作出对应的指令响应。
这有点像一个URL分发器,将前台接收到的请求发送给后面的多个业务处理器,业务处理器根据URL内容决定如何响应。

设计思路

定义一个发布接口类,包含订阅者附加、去除,订阅通知接口,派生具体的发布者类,接收指令并完成通知接口的调用。
定义一个订阅接口类,包括通知消息处理接口。派生多个具体的订阅者对指令进行各自的处理。
采用观察者模式的推模式(在进行通知广播的时候,将观察者需要的全部信息都提供给观察者,本示例需要的就是一个命令字符串,采用推模式感觉更解耦)。

UML

在这里插入图片描述

代码

#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
class Processor
{
public:
    virtual void execute(string cmd) = 0;
};

class Distribute
{
protected:
    bool m_status = false;
    list <Processor*> m_processors;

public:
    virtual void attach(Processor* process) {m_processors.push_back(process);}
    virtual void detach(Processor* process) {m_processors.remove(process);}
    virtual string getCmd() = 0;
    virtual void notify()
    {
        if(m_status)
        {
            list<Processor*>::iterator iter = m_processors.begin();
            for(; iter != m_processors.end(); iter++)
            {
                (*iter)->execute(getCmd());
            }
            m_status = false;
        }
    }
};

class ConcreteDistribute : public Distribute
{
private:
    string m_cmd;
public:
    string getCmd()
    {
        if(m_status == false)
        {
            cout<<"Please input a cmd: \n";
            getline(cin, m_cmd);
            transform(m_cmd.begin(), m_cmd.end(), m_cmd.begin(), ::toupper);
            m_status = true;
        }
        return m_cmd;
    }
};

class DirProcessor : public Processor
{
public:
    void execute(string cmd)
    {
        if(cmd == "DIR") cout<<"DirProcessor say: This is a DIR cmd!\n";
        else cout<<"DirProcessor say: I don't know this cmd!\n";
    }
};

class DelProcessor : public Processor
{
public:
    void execute(string cmd)
    {
        if(cmd == "DEL") cout<<"DelProcess say: This is a DEL cmd!\n";
        else cout<<"DelProcessor say: I don't know this cmd!\n";
    }
};

int main()
{
    ConcreteDistribute* distributer = new ConcreteDistribute();
    DirProcessor* dirProcessor = new DirProcessor();
    DelProcessor* delProcessor = new DelProcessor();
    distributer->attach(dirProcessor);
    distributer->attach(delProcessor);
    distributer->getCmd();
    distributer->notify();
    distributer->detach(delProcessor);
    distributer->detach(dirProcessor);
    delete delProcessor;
    delete dirProcessor;
    delete distributer;

    return 0;
}

运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值