/**
《观察者模式》
是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
观察者模式建议你为发布者类添加订阅机制, 让每个对象都能订阅或取消订阅发布者事件流。
实际上, 该机制包括 :
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();
}
C++观察者模式
最新推荐文章于 2023-03-18 09:22:45 发布