C++设计模式之观察者模式(Observer)

所属分类: 软件编程 / C 语言 阅读数: 70
收藏 0 赞 0 分享

观察者模式通常的叫法叫做订阅-发布模式,类似于报刊杂志的订阅,观察者和被观察者就是读者和邮局的关系,读者先要在邮局订阅想要的报刊,当报刊发行时,邮局会将报刊邮寄到读者家里。观察者(Observer)和被观察者(Listener)也是这种关系,Observer将自己attach到Listener中,当Listener触发时Notify所有Observer.

作用

在观察者模式中,被观察者维护观察者对象的集合,当被观察者对象变化时,它会通知观察者。观察者模式主要是用于解决对象之间一对多的关系。

类视图

实现

class Observer 
{
public:
  virtual ~Observer() {};
  virtual void Update(const std::string &msg)= 0; 
protected:
  Observer(){};
};


class Listener
{
public:
  virtual ~Listener() {};
  void attach(Observer* obsvr) 
  {
    m_observers.push_back(obsvr);
  }
  void remove(Observer* obsvr)
  {
    m_observers.remove(obsvr);
  }
  void notify(const std::string &msg)
  {
    list<Observer*>::iterator iter = m_observers.begin(); 
    for(; iter != m_observers.end(); iter++) 
      (*iter)->Update(msg); 
  }
private: 
  list<Observer* > m_observers; //观察者链表 
};


class logRunner : public Listener
{
public:
  virtual ~logRunner(){};
  void addmsg(const std::string &msg)
  {
    nofity(msg);
  }
}

class logGui : public Observer
{
public:
  virtual ~Observer(){};
  void Update(const std::string &msg)
  {
    cout<< "Gui log show : "<< msg <<endl;
  }
}

class logFile : public Observer
{
public:
  virtual ~Observer(){};
  void Update(const std::string &msg)
  {
    cout<< "file log write : "<< msg <<endl;
  }
}

class logDebug : public Observer
{
public:
  virtual ~Observer(){};
  void Update(const std::string &msg)
  {
    cout<< "Debug log out : "<< msg <<endl;
  }
}


class logDataBase : public Observer
{
public:
  virtual ~Observer(){};
  void Update(const std::string &msg)
  {
    cout<< "DataBase log in : "<< msg <<endl;
  }
}

int main()
{
  logRunner Runner;
  logGui gGui;
  logFile gFile;
  logDebug gDebug;
  logDataBase gDataBase;
  
  Runner.attach(&gGui);
  Runner.attach(&gFile);
  Runner.attach(&gDebug);
  Runner.attach(&gDataBase);
  
  Runner.addmsg("app is setup");
}

Observer中update一般为纯虚,通过子类各自实现,这里只是保证调用的接口一致,Listener中的attach、remove、notify一般建议不进行虚化,子类不用关心其内部的聚合内容,通过调用notify实现消息分发即可。当然也可以虚化,将这一系列的操作放到子类进行实现。
调用者应该注意在多线程环境中的使用环境,做好数据的同步工作。

应用场景

  • 当一个对象改变需要通知到其他对象,而我们不确定由多少对象需要通知时;
  • 当一个对象必须通知其他对象,而不需要知道对象是什么实现时;
  • 对于一堆对象,包含同样的状态或同样的数据,通过同一个条件进行更新时。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

利用C语言来求最大连续子序列乘积的方法

这篇文章主要介绍了利用C语言来求最大连续子序列乘积的方法,基本的思路以外文中还附有相关ACM题目,需要的朋友可以参考下
收藏 0 赞 0 分享

用C语言判断一个二叉树是否为另一个的子结构

这篇文章主要介绍了用C语言判断一个二叉树是否为另一个的子结构,是数据结构学习当中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言实现的阶乘,排列和组合实例

这篇文章主要介绍了C语言实现的阶乘,排列和组合的方法,涉及C语言数学运算的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言查找数组里数字重复次数的方法

这篇文章主要介绍了C语言查找数组里数字重复次数的方法,涉及C语言针对数组的遍历与判断技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言简单实现计算字符个数的方法

这篇文章主要介绍了C语言简单实现计算字符个数的方法,涉及C语言针对字符串的简单遍历与判定技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

c实现linux下的数据库备份

本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

C++获得文件状态信息的方法

这篇文章主要介绍了C++获得文件状态信息的方法,包括文件状态信息、文件所在磁盘盘符、文件创建时间、访问时间及修改日期等,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言按关键字搜索文件夹中文件的方法

这篇文章主要介绍了C语言按关键字搜索文件夹中文件的方法,涉及C语言文件操作及字符串查找的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言之字符串模糊查询方法的实现

本篇文章主要为大家介绍字符串模糊查询的C语言程序编写方法,有需要的朋友可以参考下
收藏 0 赞 0 分享

C语言实现BMP转换JPG的方法

这篇文章主要介绍了C语言实现BMP转换JPG的方法,涉及C#图片格式转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多