观察者模式及c++实现
观察者模式概念:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并自己主动更新。“Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.” – GoF
UML图

特点:
1.观察者模式定义了对象之间一对多的关系。
2.主题(也就是可观察者)用一个共同的接口来更新观察者。
3.观察者和可观察者用松耦合的方式结合,可观察者不知道观察者的细节,仅仅知道观察者实现了观察者接口
4.有多个观察者时,不能够依赖特点的通知次序。
C++源码:
Observer.h
/*
观察者模式:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,
依赖它的对象都会收到通知,并自己主动更新。
*/ #include <iostream>
#include <vector>
using namespace std; class Observer; //Account抽象类,用作接口
class Account
{
protected:
vector<Observer*> observer;
double balance;
public:
virtual void add_observer(Observer *o)=0;
virtual void remove_observer(Observer *o)=0;
virtual void notify_observer()=0;
virtual void set_balance(double balance)=0;
virtual double get_balance()=0;
public:
virtual ~Account()
{
cout<<"in the destructor of Account"<<endl;
}
}; //Observer抽象类,用作接口
class Observer
{
protected:
Account *account;
public:
Observer(Account *account):account(account) {}
virtual void handle_event()=0;
virtual void set_account_balance(double balance)=0;
virtual ~Observer()
{
cout<<"in the destructor of Observer"<<endl;
}
}; //BankAccount详细类,继承了ACcount抽象类
class BankAccount:public Account
{
public: ~BankAccount()
{
cout<<"in the destructor of BankAccount"<<endl;
} public:
void add_observer(Observer *o)
{
observer.push_back(o);
}
void remove_observer(Observer *o)
{
for(vector<Observer*>::iterator it=observer.begin(); it!=observer.end(); it++)
{
if(o==*it)
{
observer.erase(it);
return;
}
}
}
void notify_observer()
{
for(vector<Observer*>::const_iterator it=observer.begin(); it!=observer.end(); it++)
{
(*it)->handle_event();
}
}
void set_balance(double balance)
{
this->balance=balance;
notify_observer();
}
double get_balance()
{
return balance;
} }; class ATM:public Observer
{
public:
ATM(Account *account):Observer(account)//将acount传递给基类Observer的构造函数
{
}
~ATM()
{
cout<<"in the destructor of ATM"<<endl;
}
public:
void handle_event()
{
cout<<"ATM: the balance of bank accont is changed to "<<account->get_balance()<<endl;
}
void set_account_balance(double balance)
{
account->set_balance(balance);
}
}; class InternetBankService:public Observer
{
public:
InternetBankService(Account *account):Observer(account) {}
~InternetBankService()
{
cout<<"in the destructor InternetBankService "<<endl;
}
public:
void handle_event()
{
cout<<"IBS: the balance of bank account is changed to:"<<account->get_balance()<<endl;
}
void set_account_balance(double balance)
{
account->set_balance(balance);
} };
Observer.cpp
#include "Observer.h"
int main(int argc, char **argv)
{
Account *account=new BankAccount();
Observer *atm_observer=new ATM(account);
Observer *ibs_observer=new InternetBankService(account); account->add_observer(atm_observer);
account->add_observer(ibs_observer); account->set_balance(1000.12); cout<<"Event is triggered by atm_observer"<<endl;
cout<<"============="<<endl;
atm_observer->set_account_balance(1000.23); cout<<"Event is triggered by ibs_observer"<<endl;
cout<<"============="<<endl;
ibs_observer->set_account_balance(1000.36); delete atm_observer;
delete ibs_observer;
return 0;
}
例2:
Test_Observer.cpp
/*
千万要注意对象切割问题的出现。一定要理解。
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std; class Observer
{
protected:
string name;
public:
virtual void update()
{
cout<<"Observer"<<endl;
}
}; class Man:public Observer
{
public:
Man(string name)
{
this->name=name;
}
void update()
{
cout<<name<<" Man is coming"<<endl;
}
};
class Woman:public Observer
{
public:
Woman(string name)
{
this->name=name;
}
void update()
{
cout<<name<<" Woman is leaving"<<endl;
}
}; class Subject
{
private:
vector<Observer*> obser;
public:
void add(Observer &ob)
{
obser.push_back(&ob);
}
void notify()
{
for (vector<Observer*>::iterator it=obser.begin(); it!=obser.end(); it++)
{
(*it)->update();
}
}
}; int main()
{
Subject secret;
Man m1("m1--");
Man m2("m2--");
Woman w1("w1");
Woman w2("w2"); secret.add(m1);
secret.add(m2);
secret.add(w1);
secret.add(w2); secret.notify();
return 0; }
观察者模式及c++实现的更多相关文章
- 23种设计模式--观察者模式-Observer Pattern
一.观察者模式的介绍 观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...
- 谈谈JS的观察者模式(自定义事件)
呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...
- ObserverPattern(观察者模式)
import java.util.ArrayList; import java.util.List; /** * 观察者模式 * @author TMAC-J * 牵一发而动全身来形容观察者模式在合适 ...
- java观察者模式
像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...
- Backbone源码解析(六):观察者模式应用
卤煮在大概一年前写过backbone的源码分析,里面讲的是对一些backbone框架的方法的讲解.这几天重新看了几遍backbone的源码,才发现之前对于它的理解不够深入,只关注了它的一些部分的细节和 ...
- PHP 高级编程(3/5) - 使用SPL(标准PHP库)实现观察者模式
SPL(标准PHP库 - Standard PHP Library)是PHP5面向对象功能中重要的部分.原文解释是这样的“The Standard PHP Library (SPL) is a col ...
- 设计模式--观察者模式初探和java Observable模式
初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...
- 学C#之设计模式系列笔记(2)观察者模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,观察者模式,https://zh.wikipedia.o ...
- PHP 观察者模式
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. [观察者模式中主要角色] 1.抽象主题(Subject)角色: 抽象主题提供了增加 ...
- GJM: 设计模式 - 观察者模式
GJM : 观察者模式 视频地址: http://www.imooc.com/learn/415 本课程通过一个天气预报的发布和订阅案例,来讲解观察者模式在Java项目中的应用.主要包括观察者模式的结 ...
随机推荐
- iview select下拉bug
1场景:弹框内有一个下拉组件(支持搜索),当选择完数据后弹框关闭,再次打开后,下拉框内的数据是刚才选中的数据.原因:分析后觉得是搜索内容没有清空,导致下拉的数据只有一个解决:调用下setQuery方法 ...
- 菜鸟的HTML学习之路
开发网站流程 确定风格.功能(论坛.留言板.支付.用户登录等). 美工制作网页效果图(首页.列表页.内容页). 制作人员切图排版,排成网页形式. 后台程序开始写程序. 前台与后台结合. HTML注释 ...
- 解决移动端touch事件(touchstart/touchend) 的穿透问题
情景: 我们在移动端点击事件click对比touchend会有很明显的300ms的延迟,为啥? 浏览器在 click 后会等待约300ms去判断用户是否有双击行为(手机需要知道你是不是想双击放大网页内 ...
- 微信小程序为什么不被看好?
我自认为对新技术还是比较有热情的,可对于小程序这个“新技术”,我却完全是被动的.去年9月份的时候,微信小程序开始内测,瞬间引爆朋友圈.知乎等一众分享平台.当时我大概了解了一下,觉得从技术角度上来说没啥 ...
- asp.net mvc +easyui 实现权限管理(一)
权限是每个企业应用必须的模块,可以简单,也能比较复杂.目前我们公司的权限要求是 能管控页面.字段.按钮.以及数据权限. 正好公司的进销存系统权限模块由我负责.做完后做下记录是个不错的习惯,知识是慢慢积 ...
- flutter圆角效果的实现
new Material( borderRadius: BorderRadius.circular(20.0), shadowColor: Colors.blue.shade200, elevatio ...
- 聊一聊数组的map、reduce、foreach等方法
聊聊数组遍历方法 JS 数组的遍历方法有好几个: every some filter foreach map reduce 接下来我们来一个个地交流下. every() arr.every(callb ...
- leetCode题解之Number of Lines To Write String
1.题目描述 2.分析 使用一个map将字母和数字对应起来,方便后续使用. 3.代码 vector<int> numberOfLines(vector<int>& wi ...
- Squid安装配置和使用
文:铁乐与猫 环境 centos 6.5 x64 安装 最简单的一种就是yum安装. yum install squid 版本 rpm -qa | grep squid squid-3.1.23-16 ...
- centos7.4之zabbix4.0的fping监控
参考博文: https://www.cnblogs.com/lei0213/p/8859326.html 注释:他是额外安装fping的:因为我yum安装的zabbix,fping就已经自带了:安装步 ...