C++观察者模式

/**
    《观察者模式》
    是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。

    观察者模式建议你为发布者类添加订阅机制, 让每个对象都能订阅或取消订阅发布者事件流。
    实际上, 该机制包括 :
    1) 一个用于存储订阅者对象引用的列表成员变量; 
    2) 几个用于添加或删除该列表中订阅者的公有方法。

    所有订阅者都必须实现同样的接口, 发布者仅通过该接口与订阅者交互。 
    接口中必须声明通知方法及其参数, 这样发布者在发出通知时还能传递一些上下文数据。

    如果你的应用中有多个不同类型的发布者, 且希望订阅者可兼容所有发布者, 那么你甚至可以进一步让所有订阅者遵循同样的接口。 
    该接口仅需描述几个订阅方法即可。 这样订阅者就能在不与具体发布者类耦合的情况下通过接口观察发布者的状态。
 */

// 整体可以是两个接口(发布者和订阅者),以及两个接口下的两类实体

#include <iostream>
#include <string>
#include <list>

// 观察者的接口
class IObserver
{
public:
    // message 是发布者发布的信息
    virtual void Update(const std::string &message_from_subject) = 0;
    virtual ~IObserver() {}
};

// 发布者接口
class ISubject
{
public:
    virtual void Attach(IObserver *observer) = 0;
    virtual void Detach(IObserver *observer) = 0;
    virtual void Notify() = 0;
    virtual ~ISubject() {}
};


// 发布者实体
class Subject : public ISubject
{
private:
    std::list<IObserver *> list_observers_;
    std::string message_;

public:
    void Attach(IObserver *observer) override
    {
        list_observers_.push_back(observer);
    }

    void Detach(IObserver *observer) override
    {
        list_observers_.remove(observer);
    }

    void Notify() override
    {
        for (auto it = list_observers_.begin(); it != list_observers_.end(); ++it)
        {
            (*it)->Update(message_);
        }
    } 

    // 更新消息
    void CreateMessage(std::string message = "default")
    {
        message_ = message;
        Notify();
    }

    // 模拟业务逻辑的状态改变时,会发送通知
    void ChangeSomthing()
    {
        this->message_ = "somthing had changed!";
        Notify();
    }
};


// 观察者实体
class Observer : public IObserver
{
private:
    std::string message_from_subject_;
    Subject &subject_;
    static int static_number_;
    int number_;

public:
    Observer(Subject &subject) : subject_(subject)
    {
        this->subject_.Attach(this);    // 注册
        ++Observer::static_number_;     // 计数器++
        this->number_ = Observer::static_number_;
    }

    void Update(const std::string &message_from_subject) override
    {
        message_from_subject_ = message_from_subject;
        std::cout << "观察者[ " << this->number_ << " ]收到发布者的消息:" << message_from_subject << std::endl;
    }

    void Remove()
    {
        subject_.Detach(this);
    }

};

int Observer::static_number_ = 0;

int main()
{
    // 定义一个发布者
    Subject subject;

    // 定义n个观察者
    for (int i = 0; i < 5; ++i)
    {
        Observer *observer = new Observer(subject);
    }

    // 发布者先推送一下消息
    subject.Notify();

    // 发布者手动修改消息
    subject.CreateMessage("this is a message.");

    // 发布者做出变化
    subject.ChangeSomthing();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子砰砰枪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值