观察者模式及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项目中的应用.主要包括观察者模式的结 ...
随机推荐
- Android 图板之保存图像
(1)为了能适应多种屏幕尺寸的手机,我们在创建图像的时候就要根据用户手机屏幕的宽高像素来创建. (2)该软件将把图形保存到sdcard中,在保存之前,需要检测sdcard是否存在,是否可写入.如通过以 ...
- idea 自动导入包设置
- mybatis resultMap 映射配置
现有数据库表: CREATE TABLE `dept_p` ( `DEPT_ID` ) NOT NULL, `DEPT_NAME` ) DEFAULT NULL, `PARENT_ID` ) DEFA ...
- sun.misc.BASE64Encoder在Eclipse中不能直接使用的原因和解决方案
1.为什么在Eclipse中不能直接使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder呢? 因为sun.misc.BASE64Encoder和sun.mis ...
- spring boot(15)-异常处理
异常传递 如图:服务层和dao层的异常最终都会到达控制层,控制层的异常则会自动记入logback日志系统.所以我们应该在控制层来捕获系统异常 捕获控制层异常 import org.slf4j.Logg ...
- 【Kendo UI系列开发使用笔记】01-简单介绍
ps:接触telerik出品的kendo ui系列已经快有一年了,使用过程中也在不断踩坑填坑.这套UI用起来还是非常爽的,尤其asp.net mvc版的配合lambda表达式来配置参数非常流畅.这次对 ...
- windows下建立netcore控制台程序,然后传送到centos7下的docker容器里运行
1.首先,在window下用vs2017开发netcore控制台项目. 2.把建立好的项目传送到centos7下面的容器里. docker cp sharefoldersforwindows/ 359 ...
- c# 编译期常量const和运行时常量readonly
注意:const编译期常量是编译的时候就确定的,可以查看IL代码,是写死的.如果另一个程序集引用后,该程序集没有进行编译,则值不会改变. 看效果: 项目中有2个程序集: 其中:常量在这个程序集中定义并 ...
- Oracle EBS 启动调试日志
SELECT * FROM dba_source t WHERE t.TEXT LIKE '%PO_PDOI_TAX_CALCULATION_ERR%' FND:启用调试日志 FND:调试日志级别 ...
- 用jQuery Validate+layer插件实现好看的表单提交效果
作为初学者,以前做表单验证都是自己写的,目的是让自己更好的了解代码,加深自己对javascript的理解,但是其实在很久都知道有一个很好用的表单验证插件:jQuery Validate.js,一直都没 ...