1. 说说简单的函数回调

首先说说一种简单的函数回调机制(一种通过获取对象的指针来进行函数的调用方法)以下是代码演示---

这是观察者(被回调)部分:

class Observer
{
public:
// 抽象观察者的纯虚函数
virtual void UpdateMessage() = 0;
}; class ConcreteObserver : public Observer
{
public:
// 实现抽象类的纯虚函数
void UpdateMessage();
} void ConcreteObserver::UpdateMessage()
{
// 这里实现详细的操作
} class Subject
{
public:
Subject(Observer* observer = NULL); void OnMessageChanged(); private:
Observer* m_observer;
};

以下是被观察者(主动调用)部分:

Subject::Subject(Observer* observer)
{
// 将Observer的对象指针传进来并复制
m_observer = observer;
} void Subject::OnMessageChanged()
{
if(m_observer)
{
// 通过多态机制下的指针回调观察者的函数
m_observer->UpdateMessage();
}
}

如上所看到的,程序中的一个对象通过获取还有一个对象的指针,来进行函数的调用。这不是类之间的直接调用,仅仅因该对象指针是在多态下定义的。

进一步拓展,假设有一个或多个多个观察者来关注一个或多个对象,那么就能够用通常所说的观察者模式来实现了。

2. 观察者模式的应用场合和特点

观察者模式一般出如今这种场合:存在观察者和被观察对象。详细样例,比方订阅邮件或杂志, 微博关注某某主题等。当你在微博上关注了某个主题后,当这个主题有新的信息发出来时,你的微博主页将会对应收到它的更新信息。

而观察者模式提供了这种一个对象模型,使得对象们(主题和观察者)之间松耦合:

(1)观察者的更替或数据模块的更新不会影响主题的存在。

(2)观察者和主题类能够方便的独立地被程序其它模块使用。

(3)一个主题能够注冊多个观察者,也能够动态删除观察者; 一个观察者也能够注冊多个主题,也能够撤销注冊。

比如一份天气预报能够被多个用户订阅,当数据更新时会通知全部注冊的用户。一个用户也能够订阅多份天气预报,广州的,珠海的等等。

3.简单的代码演示

(1)演示的功能能够用这个类图来表达,类图中定义了Subject和Observer两个接口,并定义了两个详细主题类和三个详细观察者类。

(2)详细代码实现

首先是主题类,分别定义了类ConcreteSubjectA和类ConcreteSubjectB。

class Subject
{
public:
virtual void registerObserver(shared_ptr<Observer> observer) = 0;
virtual void removeObserver(shared_ptr<Observer> observer) = 0;
virtual void notifyObserver() = 0;
}; class ConcreteSubjectA : public Subject
{
public:
ConcreteSubjectA()
{
// do something here
testValue = 1;
} void registerObserver(shared_ptr<Observer> observer)
{
observersList.push_back(observer);
}
void removeObserver(shared_ptr<Observer> observer)
{
observersList.remove(observer);
} void notifyObserver()
{
for (list<shared_ptr<Observer> >::iterator it = observersList.begin();
it != observersList.end(); ++it)
{
(*it)->updateData(testValue);
}
} private:
list<shared_ptr<Observer> > observersList;
int testValue;
}; class ConcreteSubjectB : public Subject
{
public:
ConcreteSubjectB()
{
// do something here
testValue = 2;
} void registerObserver(shared_ptr<Observer> observer)
{
observersList.push_back(observer);
}
void removeObserver(shared_ptr<Observer> observer)
{
observersList.remove(observer);
} void notifyObserver()
{
for (list<shared_ptr<Observer> >::iterator it = observersList.begin();
it != observersList.end(); ++it)
{
(*it)->updateData(testValue);
}
} private:
list<shared_ptr<Observer> > observersList;
int testValue;
};

接着是观察者类,分别定义了类ConcreteObserverA,类ConcreteObserveB,类ConcreteObserverC。

class Observer
{
public:
virtual void updateData(int val) = 0;
}; class ConcreteObserverA : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In A :" << val <<endl;
}
}; class ConcreteObserverB : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In B :" << val <<endl;
}
}; class ConcreteObserverC : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In C :" <<val <<endl;
}
};

然后,我们能够这样使用他们:

 int main()
{
shared_ptr<Subject> subjectA(new ConcreteSubjectA());
shared_ptr<Subject> subjectB(new ConcreteSubjectB()); shared_ptr<Observer> observerA(new ConcreteObserverA());
shared_ptr<Observer> observerB(new ConcreteObserverB());
shared_ptr<Observer> observerC(new ConcreteObserverC()); subjectA->registerObserver(observerA);
subjectA->registerObserver(observerB);
subjectB->registerObserver(observerC); // 主题A有更新时将通知观察者A,B
subjectA->notifyObserver();
// 主题B有更新时将通知观察者C
subjectB->notifyObserver(); return 0;
}

学习设计模式--观察者模式(C++)的更多相关文章

  1. 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式

    装饰者模式是JDK中还有一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源代码,也是为了学习大牛们的设计思路.--- ...

  2. (转)C++设计模式——观察者模式

    转自:http://www.jellythink.com/archives/359 前言 之前做了一个性能测试的项目,就是需要对现在的产品进行性能测试,获得测试数据,然后书写测试报告,并提出合理化的改 ...

  3. C++设计模式——观察者模式(转)

    前言 之前做了一个性能测试的项目,就是需要对现在的产品进行性能测试,获得测试数据,然后书写测试报告,并提出合理化的改善意见.项目很简单,我们获得了一系列性能测试数据,对于数据,我们需要在Excel中制 ...

  4. js设计模式-观察者模式

    定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...

  5. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  6. 小菜学习设计模式(五)—控制反转(Ioc)

    写在前面 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Metho ...

  7. 小菜学习设计模式(四)—原型(Prototype)模式

    前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...

  8. 小菜学习设计模式(三)—工厂方法(Factory Method)模式

    前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...

  9. 小菜学习设计模式(二)—单例(Singleton)模式

    前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...

随机推荐

  1. form表单提交

    1.form表单提交.html页面失败 <%--客户端form--%> <form id="form2" action="LoginOne.html&q ...

  2. SQL从入门到基础 - 04 SQLServer基础2(数据删除、数据检索、数据汇总、数据排序、通配符过滤、空值处理、多值匹配)

    一.数据删除 1. 删除表中全部数据:Delete from T_Person. 2. Delete 只是删除数据,表还在,和Drop Table(数据和表全部删除)不同. 3. Delete 也可以 ...

  3. XFire构建服务端Service的两种方式

    1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...

  4. MySQL利用binlog来恢复数据库

    1.根据binlog解析出所有ring数据库的所有sql [mysql@localhost ]$ mysqlbinlog --no-defaults --database=ring --start-d ...

  5. BOM和DOM的联系和区别

    BOM中的对象 Window对象: 是整个BOM的核心,所有对象和集合都以某种方式回接到window对象.Window对象表示整个浏览器窗口,但不必表示其中包含的内容. Document对象: 实际上 ...

  6. 【Ecstore2.0】计划任务/队列/导入导出 的执行问题

    [环境]CENTOS6.3 + wdcp(php5.3) [症状]可正常加入队列,但不执行队列 [原因]大部份都是用户权限造成 [原理] Ecstore2.0的导入导出.发送邮件.日常清理备份等任务操 ...

  7. 手机时间选择插件 Jquery

    // 时间选择 var currYear = (new Date()).getFullYear() var opt_data = { preset: 'date', //日期 theme: 'andr ...

  8. STL之优先队列(priority_queue)

    转自网上大牛博客,原文地址:http://www.cnblogs.com/summerRQ/articles/2470130.html 先回顾队列的定义:队列(queue)维护了一组对象,进入队列的对 ...

  9. 周末献礼 MyVoix2.0.js 麦克风波形绘制(一)

    最近更新了之前发布的语音识别框架MyVoix,加入了麦克风的波形分析效果.没有看过MyVoix介绍的同学请猛戳(传送门) Github地址 在新的更新中,波形分析可以绑定麦克风源,也可以单独配合别的音 ...

  10. MemCache内存缓存系统

    memcached是一种缓存技术, 他可以把你的数据放入内存,从而通过内存访问提速,因为内存最快的, memcached技术的主要目的提速, 默认情况下占用的端口号为:11211. 在memachec ...