返回

C++设计模式 观察者模式(发布者给订阅者发通知)

发布时间:2023-10-27 03:05:55 337


文章目录

  • ​​1. 观察者模式: ObserverPattern​​
  • ​​2. 应用​​
  • ​​3. 逻辑代码​​
  • ​​4. 代码示例​​

1. 观察者模式: ObserverPattern

定义对象间的一种一对多依赖关系, 使得每当一个对象状态发生改变时, 其相关依赖对象皆得到通知并自动更新

2. 应用

最经典的应用就是我们订阅邮件, 当有新的文章发表, 发布者会通过邮件给我们这些订阅者发送通知, 我们就知道了更新的文章

3. 逻辑代码

  • 创建list链表保存所有的观察者基类指针
  • 创建state状态标志位, 状态转换后通知更新给所有的观察者
// 抽象订阅者, 贷款人 为所有的具体观测者定义一个接口, 在得到老大的通知时, 更新自己
class Observer{
public:
virtual ~Observer(){}
virtual void Update() = 0;
};

// 主体对象, 通知者, 借款人
class Subject{
private:
list observers_; // 保存订阅者

public:
// 增加订阅者
void Attach(Observer *observer){
observers_.push_back(observer);
}

// 移除订阅者
void Detach(Observer *observer){
observers_.remove(observer);
}

// 通知订阅者
void Notify(){
for(const auto &a : observers_){
a->Update();
}
}
};


// 通知者主体
class ConcreteSubject: public Subject{
private:
string subjectState_;
public:
string getState(){
return this->subjectState_;
}

void SetState(string value){
subjectState_ = value;
}
};

// 订阅者主体
class ConcreteObserver : public Observer{
private:
string name_;
string observerState_;
ConcreteSubject *subject_ = nullptr;
public:
ConcreteObserver(ConcreteSubject *subject, string name): subject_(subject), name_(name){}
void Update(){
observerState_ = subject_->getState(); // 得到通知者当前状态
cout << "订阅者" << name_ <<" 的新状态是" << observerState_ << endl;
}

ConcreteSubject* getSubject(){
if(subject_ != nullptr) return subject_;
}

void setSubject(ConcreteSubject *subject){
subject_ = subject;
}
};


int main(int argc, char const *argv[])
{
ConcreteSubject *s = new ConcreteSubject(); // 创建一个通知者, 用来给订阅者发送信息
ConcreteObserver *x = new ConcreteObserver(s, "X");
ConcreteObserver *y = new ConcreteObserver(s, "Y");
ConcreteObserver *z = new ConcreteObserver(s, "Z");

s->Attach(x); // 给通知者增加一个订阅者X,
s->Attach(y); // 给通知者增加一个订阅者Y,
s->Attach(z); // 给通知者增加一个订阅者Z,

s->SetState("ABC");
s->Notify();

ConcreteSubject *s2 = new ConcreteSubject(); // 创建另一个通知者
s2->Attach(x); // 给这个通知者增加一个订阅者
s2->SetState("BEEE"); // 设置通知者当前状态
x->setSubject(s2); // 给这个订阅者更换通知者
s2->Notify(); // 给所有的订阅者通知


delete s;
delete x;
delete y;
delete z;
delete s2;

return 0;
}

4. 代码示例

C++设计模式 观察者模式(发布者给订阅者发通知)_#include

#include 
#include // reverse
#include
#include

using namespace std;

/* 观察者模式:
有两个银行, 赵四和王五开的
张三跟赵四和王五借款后(行为), 没有钱(状态), 所以无法还给银行,只能等有钱才能还
银行如何知道张三有钱呢?
方法1: 天天给张三打电话询问
方法2: 张三有了通知银行(显然这种方法更高效)
下面的代码就是实现了这样的一种方案:
当一个对象状态发生改变, 其他依赖对象得到通知, 并进行自动的更新
*/

// 银行
class Credit{
public:
virtual void takeMoney()=0;
};

// 赵四家的银行
class Zhao4: public Credit{
public:
void takeMoney(){
cout<< "赵四收到了通知, 拿到了钱" < }
};

// 王五家的银行
class Wang5: public Credit{
public:
void takeMoney(){
cout<< "王五收到了通知, 拿到了钱" < }
};

// 借款方
class Debit{
public:
virtual void borrow(Credit *c)=0; // 借钱
virtual void notifyCredit() = 0; // 通知
};


// 借款人 张三
class ZhangSan: public Debit{
private:
list allCredits; // 表示贷款了几个银行
bool state = false; // 表示有钱没钱
public:
void borrow(Credit *c){
allCredits.emplace_back(c);
}
// 遍历所有银行, 通知有钱了
void notifyCredit(){
for(Credit *a: allCredits){
a->takeMoney();
}
}
};

int main() {
Credit *zhao4 = new Zhao4();
Credit *wang5 = new Wang5();

Debit *zhangsan = new ZhangSan();
zhangsan->borrow(zhao4);
zhangsan->borrow(wang5);

// 一定时间后, 转到钱了, state改变, 通知所有银行
zhangsan->notifyCredit();
return 0;
}


特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
C++设计模式 模板方法模式(多态) 2023-10-27 00:17:48