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

相关标签:
文章目录
- 1. 观察者模式: ObserverPattern
- 2. 应用
- 3. 逻辑代码
- 4. 代码示例
1. 观察者模式: ObserverPattern
定义对象间的一种一对多依赖关系, 使得每当一个对象状态发生改变时, 其相关依赖对象皆得到通知并自动更新
2. 应用
最经典的应用就是我们订阅邮件, 当有新的文章发表, 发布者会通过邮件给我们这些订阅者发送通知, 我们就知道了更新的文章
3. 逻辑代码
- 创建list链表保存所有的观察者基类指针
- 创建state状态标志位, 状态转换后通知更新给所有的观察者
// 抽象订阅者, 贷款人 为所有的具体观测者定义一个接口, 在得到老大的通知时, 更新自己
class Observer{
public:
virtual ~Observer(){}
virtual void Update() = 0;
};
// 主体对象, 通知者, 借款人
class Subject{
private:
listobservers_; // 保存订阅者
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. 代码示例
#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:
listallCredits; // 表示贷款了几个银行
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;
}
文章来源: https://blog.51cto.com/u_15888063/5879399
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报