设计模式C++实现--Observer模式
2019独角兽企业重金招聘Python工程师标准>>>
观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
介绍
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
实现
观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。
步骤 1
创建 Subject 类。
// 被观察者
class Subject{
private:list<Observer *> _observers;int _state;public:int GetState(){return _state;}void SetState(int state){_state = state;NotifyAllObservers();}void Attach(Observer * observer){_observers.push_back(observer);}void NotifyAllObservers(){list<Observer*>::iterator iter = _observers.begin();for(;iter != _observers.end();iter++){(*iter)->update();}}
};
步骤 2
创建 Observer 类。
class Subject;class Observer{
protected:Subject * _subject;public:Observer(Subject *subject) : _subject(subject) {}virtual ~Observer(){}virtual void update() = 0;
};
步骤 3
创建实体观察者类。
class BinaryObserver : public Observer{
public:BinaryObserver(Subject *subject) : Observer(subject) {_subject->Attach(this);}void update() override {std::cout << "Binary string :" << _subject->GetState() << std::endl;}
};class OctalObserver : public Observer{
public:OctalObserver(Subject *subject) : Observer(subject) {_subject->Attach(this);}void update() override {std::cout << "Octal String:" << _subject->GetState() << std::endl;}
};class HexaObserver : public Observer{
public:HexaObserver(Subject *subject) : Observer(subject) {_subject->Attach(this);}void update() override {std::cout << "Hex String:" << _subject->GetState() << std::endl;}
};
步骤 4
使用 Subject 和实体观察者对象。
Subject * subject = new Subject();Observer * o1 = new BinaryObserver(subject);Observer * o2 = new OctalObserver(subject);Observer * o3 = new HexaObserver(subject);subject->SetState(1);subject->SetState(3);
步骤 5
验证输出。
Binary string :1
Octal String:1
Hex String:1
Binary string :3
Octal String:3
Hex String:3
转载于:https://my.oschina.net/fileoptions/blog/1823508
设计模式C++实现--Observer模式相关推荐
- 设计模式-观察者模式(Observer模式)
观察者模式 在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变.例如,某种商品的物价上涨时会导致部分商家高兴,而消费者伤心:还有,当我们开 ...
- Java设计模式之观察者Observer模式代码示例
- C++设计模式 之 “组件协作”模式:Template Method、Strategy、Observer
"组件协作"模式: #现代软件专业分工之后的第一个结果是"框架与应用程序的划分","组件协作"模式通过晚期绑定,来实现框架与应用程序之间的松 ...
- 设计模式-Observer模式
目录 角色组成 抽象主题(Subject) 具体主题(Concrete Subject) 抽象观察者(Observer) 具体观察者(Concrete Observer) 具体实现 总结 观察者模式( ...
- 设计模式--观察者(Observer)模式
模式定义 定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新 类图 应用场景 当更改一个对象的状态可能需要更改其他对象,并且实际 ...
- 设计模式笔记 18. Observer 观察者模式(行为型模式)
18. Observer 观察者模式 2008-09-15 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系& ...
- 设计模式学习笔记——观察者(Observer)模式
设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...
- 我的实用设计模式之Observer模式
写这篇文章主要想总结自己的工作经验,温故而知新.为什么叫做实用设计模式,所谓的实用模式就是说这些模式在本人的实际工作中使用过的,而且本人相对熟悉的,经验认为这些模式的使用能给系统带来有效改善.这些模式 ...
- getinstance方法详解_二、设计模式总览及工厂模式详解
二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场 ...
最新文章
- oracle11g程序调优纪实
- printf语句中包含'\0'字符的处理
- oracle10g_vista_,Vista系统 安装Oracle10g 不成功?
- configure: error: zlib library not found
- Mac OSX 下如何显示隐藏文件
- JS中时间格式化常用方法
- 1解锁方式9008_黔隆科技刷机教程金立E7忘记密码刷机解锁降级救砖解屏幕锁账户锁教程...
- oracle 数据库 有坏快,ORACLE数据库坏块的处理 (处理无对象坏快的方法)
- 飞车手游显示服务器连接失败怎么办,qq飞车手游服务器拉取失败
- 豆瓣上最受关注的 10 本书(附下载)
- python 修改文件只读_Python脚本去除文件的只读性操作
- marked is not a function问题解决
- python空气质量提醒代码_空气质量指数查询示例代码
- 2022-2027年中国吉他行业市场调研及未来发展趋势预测报告
- SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛*(抽球游戏-fwt开立方)
- 对比前后执行计划,发现问题 - 9i
- 什么是DNS?DNS的作用?
- CPU频率是什么?主频、睿频和超频哪个更重要?
- 正则表达式:贪婪模式与懒惰模式
- 菜菜子随笔:今年的第一抹桂花香
热门文章
- 燕山大学计算机专业研究生怎么样,求助大家!重庆邮电大学计算机专业的研究生值得一读吗?...
- elasticsearch 删除满足条件的语句_ELK从入门到还未精通(二)——ElasticSearch上篇
- Java正则表达式较验手机号、邮箱
- 总结2:上传图片至指定服务器
- 用JS轻松实现一个录音、录像、录屏工具库
- 如何接触到最新的前端动态、最前沿的前端技术
- 你不知道的 Node.js 工具函数
- 10 个你可能还不知道 VS Code 使用技巧
- Flutter开发之环境搭建
- Python学习总结15:时间模块datetime time calendar (二)