• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++设计模式编程中的观察者模式使用示例

C++设计模式编程中的观察者模式使用示例

作者:十八道胡同 字体:[增加 减小] 来源:互联网 时间:2017-05-28

十八道胡同 通过本文主要向大家介绍了设计模式c++,c++设计模式pdf,大话设计模式c++,c++ qt设计模式,c++设计模式视频教程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

概述:
最近中国股市起起伏伏,当然了起伏就用商机,小明发现商机后果断想入市,买入了中国证券,他想在电脑客户端上,网页上,手机上,iPad上都可以查看到该证券的实时行情,这种情况下我们应该怎么设计我们的软件呢?我们可以这样:小明的所有客户端上都订阅中国证券这个股票,只要股票一有变化,所有的客户端都会被通知到并且被自动更新。
这就是我们的观察者模式,她定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

类图:

20163694653836.gif (375×305)

可以看出,在这个观察者模式的实现里有下面这些角色:
抽象主题(Subject)角色:主题角色把所有对观察考对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。
抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口实现。在这个示意性的实现中,更新接口只包含一个方法(即Update()方法),这个方法叫做更新方法。
具体主题(ConcreteSubject)角色:将有关状态存入具体现察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色(Concrete Observable)。具体主题角色通常用一个具体子类实现。
具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体现察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体现察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。      
从具体主题角色指向抽象观察者角色的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些ConcreteObserver类型,而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做"针对抽象编程"。

概念
观察者模式是讲有一个目标,众多个观察者去“观察”目标。目标是目标抽象类的一个派生类,观察者是观察者抽象类的一个派生类。当目标类的数据改变,所有对应的观察者对应去更新自己的状态
可以使用的情况:比如有一个世界时钟程序,有多个图形时钟去显示比如北京时区,巴黎时区,等等。如果设置一个北京时间,那么其他时钟图形都需要更新(加上或者减去时差值)。典型的图形界面设计随处可见,一个温度程序,在温度湿度等条件改变时,要更新多种显示图形来呈现。

实例
使用时,首先定义一个Subject的类对象,然后再定义多个Observer类(派生类)对象,每个Observer对象指定自己被注册到哪个Subject对象内。

示例:

#include<vector>
#include<iostream>
#include<string>
using namespace std;
 
class Subject;
 
class Observer{          //观察者抽象类
public:
 virtual void update(Subject *base)=0;
protected:
 Subject * _subject;
};
 
class Subject{          //目标抽象类
public:
 string s1;            //数据值,可以作为私有数据,然后定义一个借口去返回值,这里为了省事
 int i1;               //数据值
 void regiObserver(Observer *obs){
  _observer.push_back(obs);
   cout<<"已注册"<<endl;
 }
 void deleObserver(Observer *obs){
  _observer.pop_back();
 }
 void notify(){        //更新所有的观察者
  vector<Observer *>::iterator it;
  for(it = _observer.begin(); it != _observer.end(); it++)
   (*it)->update(this);
 } 
private:
 vector<Observer *> _observer;    //观察者容器
};
 
class FSubject:public Subject{        
public:
 void set(string s,int i){
  s1 = s;
  i1 = i;
  notify();                  //通知观察者。主函数的执行顺序已经保证了所有的观察者都已经进入容器内
 }
};
 
class FObserver :public Observer{  //第一个观察者派生类
public:
 FObserver(Subject *base):Observer(){
  _subject = base;
  _subject->regiObserver(this);
 }
 void update(Subject *base){
  s1 = base->s1;
  i1 = base->i1;
  display();
 }
 void display(){
  cout<<"更新值,第一个\n"<<s1<<endl;
  cout<<i1<<endl;
 }
private:
 string s1;
 int i1;
};
 
class SObserver:public Observer{  //第二个观察者派生类
 public:
 SObserver(Subject * base){
  _subject = base;
  _subject->regiObserver(this);
 }
 void update(Subject *base){
  s1 = base->s1;
  i1 = base->i1;
  display();
 }
  void display(){
  cout<<"更新值,第二个\n"<<s1<<endl;
  cout<<i1<<endl;
 }
private:
 string s1;
 int i1;
};
 
int main()
{
 FSubject * sub = new FSubject;
 FObserver * one = new FObserver(sub);
 SObserver * two = new SObserver(sub);
 sub->set("ok",3);
 return 0;
</div>

}
 Subject 类中的容器对象维护者所有对观察者的引用,目的是在notify中去更新所有的观察者,即通过遍历去调用观察者->update()。

观察者中的update()作用是完成观察者需要完成的事,比如在上例中,去更新自身保存的副本值,然后并显示出来。

Observer类中有一个Subject指针非常重要,在观察者的派生类的构造函数,需要去把自身的this传递过去进行注册。

Observer中有和Subject同样的数据,也可以设置为局部变量,仅仅是完成观察者需要做的事就行,而不必存储。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解C++之策略模式
  • C++设计模式编程中简单工厂与工厂方法模式的实例对比
  • 解析C++编程中如何使用设计模式中的状态模式结构
  • 详解C++设计模式编程中对访问者模式的运用
  • C++设计模式编程之Flyweight享元模式结构详解
  • 详解C++设计模式编程中责任链模式的应用
  • 深入剖析设计模式中的组合模式应用及在C++中的实现
  • 设计模式中的备忘录模式解析及相关C++实例应用
  • 深入解析设计模式中的适配器模式在C++中的运用
  • 全面解析设计模式中的建造者模式及相关C++实现

相关文章

  • 2017-05-28浅谈c++的编译和运行
  • 2017-05-28C++基础入门教程(二):数据、变量、宏等
  • 2017-05-28C语言 运算符详细介绍及示例代码
  • 2017-05-28在C++中反射调用.NET的方法(二)
  • 2017-05-28C++的try块与异常处理及调试技术实例解析
  • 2017-05-28详解C++编程中的条件判断语句if-else与switch的用法
  • 2017-05-28Linux网络编程之UDP Socket程序示例
  • 2017-05-28使用C语言实现CRC校验的方法
  • 2017-05-28Windows程序内部运行机制实例详解
  • 2017-05-28C C++ 算法实例大全

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++算法之海量数据处理方法的总结分析
    • C语言字符串大小比较
    • C++实现读取特定路径下文件夹及文件名的方法
    • C语言练习题:求1到10的阶乘之和简单实例
    • c++中的string常用函数用法总结
    • C语言中字符串常用函数strcat与strcpy的用法介绍
    • c语言求阶乘精确值示例
    • C++入门概览和尝试创建第一个C++程序
    • C++中引用&与取地址&的区别分析
    • 简单分析C语言中指针数组与数组指针的区别

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有