《大话设计模式》笔记:观察者模式

示例场景:

两个人在工作时摸鱼,同事A在看股票,同事B在看NBA。和他们关系好的前台同事负责望风,在老板来检查时通知两位同事。也有一种情况,当前台同事不在时老板来检查,结果都是A、B要停下手头的事情专心工作。

//发布者
class Subject {
public:
	void notify(){foreach (auto ob, observers) {ob.update();}}
	void attach(Observer &observer) {observers.push_back(observer);}
	void detach(Observer &observer) {observers.remove(observer);}
	void state() {return state;}
protected:
	list<Observer &>observers;
	string state;
};
class Boss : public Subject;
class Secretary : public Subject;
//观察者
class Observer {
public:
	virtual void update();
protected:
	string name;
	Subject *subect = nullptr;
};
class StockObserver: public Observer {
public:
	StockObserver StockObserver(string n, Subject *sub) : name(n), subject(sub){}
	void update() {cout << subject->state() << name << "stop stock";}
};
class NbaObserver : public Observer {
public:
	NbaObserver NbaObserver (string n, Subject *sub) : name(n), subject(sub){}
	void update() {cout << subject->state() << name << "stop NBA";}
};
//使用
Boss boss;
StockObserver A("A", &boss);
NbaObserver B("B", &boss);

boss.attach(A);
boss.attach(B);

boss.setState("i am back");
boss.notify();

通过抽象类Subject和抽象类Observer,一方面遵循了开放-封闭原则,另一方面是依赖倒转原则的体现。让程序都依赖抽象,而不是互相依赖。抽象没有依赖细节(抽象类的实现都是依赖另一抽象类,而不是其它具体类),细节依赖抽象(具体类的实现依赖抽象类,而不是另一具体类)。

观察者模式:

又叫做发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听同一主题对象,这个主题对象在状态发生变化时会通知所有观察者对象,使它们能够自动更新自己。

Subject类,可翻译为主题或抽象通知者,一般用一个抽象类实现,把所有对观察者对象的引用保存在一个容器里,每个主题可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

Observer类,抽象观察者,为所有具体的类定义一个接口,在得到主题的通知时更新自己。抽象观察者一般用一个抽象类实现。更新接口通常包含一个update方法,这个方法叫做更新方法。

使用场合:当一个对象的改变需要同时改变其它对象的时候,且不知道有多少对象有待改变。当一个抽象模型有两个方面,其中一个方面依赖另一个方面,这时用观察者模式可以将两者封装在独立的对象中使它们各自独立地改变和复用。观察者模式所做的工作其实就是解除耦合,让耦合地双方都依赖于抽象,而不是依赖于具体,从而使各自的变化都不会影响另一边的变化。

不足:抽象通知者还是依赖抽象观察者,当观察者类型多样,更新内容多样时不适合使用。此时应该使用委托。

QT中的观察者模式:

QT中的信号槽机制就是基于观察者模式实现的。
信号即通知者,槽函数即观察者,但是在QT中,通知者和观察者的关系是函数映射的关系。一个通知者对应多个观察者的关系存储在容器connectionList中,这个容器位于信号所在对象的私有类中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值