zoukankan      html  css  js  c++  java
  • 观察者模式的程序实例C++

    一、什么是观察者模式

         Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之中的一个,它的作用是当一个对象的状态发生变化时,可以自己主动通知其它关联对象,自己主动刷新对象状态。

      观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个样例,用户界面能够作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每一个类将重点放在某一个功能上,而不是其它方面。一个对象仅仅做一件事情,而且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

      观察者模式有非常多实现方式,从根本上说,该模式必须包括两个角色:观察者和被观察对象。在刚才的样例中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这种变化,而且做出对应的响应。假设在用户界面、业务数据之间使用这种观察过程,能够确保界面和数据之间划清界限,假定应用程序的需求发生变化,须要改动界面的表现,仅仅须要又一次构建一个用户界面,业务数据不须要发生变化。

      “观察”不是“直接调用”

      实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。不管是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。

      实现观察者模式的形式

      实现观察者模式有非常多形式,比較直观的一种是使用一种“注冊——通知——撤销注冊”的形式。

       实现观察者模式样例

           以下是C++的实现,在C++实现中,C++中没有接口的概念,可是能够用抽象类类取代Java或C#中的接口,在C++中抽象类中从派生类中抽象出来的函数(方法),必须定义成纯虚函数,这样在后面的使用中才干够通过基类的指针来訪问这些函数,面向对象的语言中有个特点,多态仅仅能訪问两者中共同拥有的部分。

    //实例源自http://blog.csdn.net/ocean181/archive/2010/09/11/5877621.aspx#1607956 ,主要做了点修正.

    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;

    class Observer;
    class Subject
    {
    public:
     virtual void attach(Observer *o)=0;
     virtual void change()=0;
     virtual void setWeather(string str)=0;
     virtual string getWeather()=0;
    };
    class Observer
    {
    public:
     virtual string getName()=0;
     virtual void update(Subject *s)=0;
    };

    class Earth: public Subject
    {
    private:
     string weather;
     list<Observer* >* l;//指针
    public:
     Earth()
     {
      l = new list<Observer*>;
     }
     void attach(Observer *o)
     {
      this->l->push_back(o);
     };
     void change()
     {
      for(list<Observer*>::iterator it=l->begin();it!=l->end();++it)
      {
       (*it)->update(this);
      }
     };
     void setWeather(string str)
     {
      this->weather=str;
      change();
     };
     string getWeather()
     {
      return this->weather;
     };
    };
    class Satellite:public Observer
    {
    private:
     string name;
    public:
     Satellite(string str)
     {
      name=str;
     }
     string getName()
     {
      return name;
     };
     void update(Subject *s)
     {
      cout<<this->getName()+" "+s->getWeather();
     }
    };


    int main()
    {
     Earth e;
     Satellite *s1 = new Satellite("风云一号");
     Satellite *s2 = new Satellite("风云二号");
     Satellite *s3 = new Satellite("风云三号");
     Satellite *s4 = new Satellite("风云四号");
     e.attach(s1);
     e.attach(s2);
     e.attach(s3);
     e.attach(s4);
     e.setWeather("fine");

     while(1){}
     return 0;
    }

  • 相关阅读:
    使用yeoman搭建脚手架并发布到npm
    Facebook的一些基本操作(网页版)
    Egg中使用egg-mongoose和常用的Mongoose 方法
    Vuex的使用
    跨浏览器的javascript事件的封装
    利用ngnix解决跨域问题
    webpack打包工具
    用vue-cli脚手架搭建一个仿网易云音乐的全家桶vue项目
    mac 解决mysqlclient安装失败问题
    linux之wget
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4364678.html
Copyright © 2011-2022 走看看