Observer 观察者模式

来源:互联网 发布:网络分层 编辑:程序博客网 时间:2024/05/17 06:58

    Observer 模式:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象将得到通知并自动更新。

    经常会有一组这样的对象, 当某个事件发生时, 这些对象都需要得到通知。比如 MVC 模型(Model-View-Controller,模型-视图-控制器),或者完全等价的“文档-视图设计模式”(比如 MFC)。我们希望这种通知能够自动发出, 但是, 我们不希望每次侦听通知的对象集改变时, 都要修改通知对象。我们希望将通知者和被通知者解耦。

1.让观察者以同样的方式工作.
首先, 必须找出所有希望获得通知的对象, 将这些对象称为观察者 (Observer),  因为它们在观察一个事件的发生.  所有观察者对象都必须具有相同的接口,如果它们没有相同的接口,  就必须修改目标 (subject)---就是触发事件的对象(例如 Customer 对象), 以处理各种不同类型的观察者.我不想这样做,因为这样会使目标复杂化.

2.让观察者注册自已. 
在大多数情况下,我希望观察者负责了解自己观察的是什么, 而且目标无需知道有哪些观察者依赖于自己,为此,观察者需要有一种方式向目标注册. 因为所有的观察者都是相同的类型的,所以必须在目标中添加两个方法:
    attach(Observer)--将给定的 Observer 添加到目标的观察者列表中, 也称为注册.
    detach(Observer)--从目标 Observer 列表中添加删除给定的观察者对象.

3.事件发生时通知观察者.
既然 Subject 对象有了已注册的 Observer 对象,事件发生时, Subject 对象通知 Observer 对象将非常简单. 为此,每个 Observer 类都需要实现一个名为 update 的方法.Subject 类将实现一个 notify 方法来遍历其 Observer 对象列表, 并调用每个 Observer 对象的 update 方法, 该 update 方法应该包含处理事件的代码.***

4.从目标获取信息.
只是通知每个 Observer 对象并不够. Observer 对象除了知道事件发生之外, 可能还需要关于该事件的更多信息.因此,必须在 Subject 类中添加方法, 使 Observer 对象能够获取所需的任何信息.

下图展示了这一解决方案:

observer1

图中,各个类之间的关系如下:
       1. Observer 对象在实例化时将自己添加到 Customer 类.  如果 Observer 对象需要从目标 (Customer) 那里获得更多信息, 就必须传给 update 方法一个指向调用对象的引用.
       2.当添加一个新的 Customer 对象时,notify 方法将调用这些 Observer 对象. 每个 Observer 对象都需要调用新添加的 Customer 对象的 getState 方法, 获取该对象的信息, 明确需要执行的操作. 请注意, 通常会调用几个方法以获取所需的信息.
代码:

   1:  //ObserverSimple.h
   2:   
   3:  #pragma  once
   4:   
   5:  #include <list>
   6:   
   7:  //定义状态类型
   8:  typedef int STATE;
   9:   
  10:  //提前声明 Observer 类
  11:  class MyObserver;
  12:   
  13:  //Customer 类
  14:  class Customer
  15:  {
  16:  public:
  17:      Customer(): m_CustomerState(-1){  }
  18:      virtual ~Customer();
  19:   
  20:      //
  21:      void attach(MyObserver *o);
  22:      void detach(MyObserver *o);
  23:      void notifyObs();
  24:   
  25:      //
  26:      virtual void setState(STATE nState);
  27:      virtual STATE getState();
  28:   
  29:  protected:
  30:      STATE m_CustomerState;
  31:      std::list<MyObserver *>    m_listMyObserver;
  32:  };
  33:   
  34:  //观察者: MyObserver 抽象基类
  35:  class MyObserver
  36:  {
  37:  public:
  38:      MyObserver(): m_ObserverState(-1){ }
  39:      virtual ~MyObserver(){ }
  40:   
  41:      //纯虚函数,各个派生类可能有不同的实现
  42:      //通知 MyObserver 状态了生了变化
  43:      virtual void update(Customer *pMyCust) = 0;
  44:   
  45:  protected:
  46:      STATE m_ObserverState; // 模拟保存Observer状态的变量
  47:  };
  48:   
  49:  //MyObserver 的一个派生类
  50:  class AddrVerification: public MyObserver
  51:  {
  52:  public:
  53:      //
  54:      AddrVerification():MyObserver(){}
  55:      virtual ~AddrVerification();
  56:   
  57:      //update 实现
  58:      virtual void update(Customer *pMyCust);
  59:  };
  60:   
  61:  //MyObserver 的另一个派生类
  62:  class WelcomeLetter: public MyObserver
  63:  {
  64:  public:
  65:      WelcomeLetter(): MyObserver(){ }
  66:      virtual ~WelcomeLetter();
  67:   
  68:      //update 实现
  69:      virtual void update(Customer *pMyCust);
  70:  };
   1:  //ObserverSimple.cpp
   2:   
   3:  #include "ObserverSimple.h"
   4:  #include <iostream>
   5:  #include <algorithm>
   6:   
   7:  //Customer 类实现
   8:  Customer::~Customer()
   9:  {
  10:      std::list<MyObserver*>::iterator iter1, iter2, temp;
  11:   
  12:      for(iter1 = m_listMyObserver.begin(),
  13:          iter2 = m_listMyObserver.end(); iter1 != iter2; )
  14:      {
  15:          std::cout << "~Customer(): delete an observer " << std::endl;
  16:          temp = iter1;
  17:          ++iter1;
  18:          delete *temp;
  19:      }
  20:      m_listMyObserver.clear();
  21:      std::cout << "~Customer() " << std::endl;
  22:  }
  23:   
  24:  //
  25:  void Customer::attach(MyObserver *o)
  26:  {
  27:      std::cout << "attach an Observer" << std::endl;
  28:      m_listMyObserver.push_back(o);
  29:  }
  30:  void Customer::detach(MyObserver *o)
  31:  {
  32:      std::list<MyObserver*>::iterator iter;
  33:      //寻到所用删除的 Observer 对象
  34:      iter = std::find(m_listMyObserver.begin(),
  35:                       m_listMyObserver.end(), o);
  36:   
  37:      if(iter != m_listMyObserver.end())
  38:      {
  39:          //删除对象
  40:          delete *iter;    
  41:          m_listMyObserver.erase(iter);
  42:          std::cout << std::endl 
  43:                    << "detach an Observer" << std::endl;
  44:      }
  45:  }
  46:  void Customer::notifyObs()
  47:  {
  48:      std::cout << std::endl << "Customer::notifyObs(): " << std::endl;
  49:   
  50:      std::list<MyObserver*>::iterator iter;
  51:      for(iter = m_listMyObserver.begin(); 
  52:          iter != m_listMyObserver.end(); ++iter)
  53:      {
  54:          (*iter)->update(this);
  55:      }
  56:  }
  57:   
  58:  //
  59:  void Customer::setState(STATE nState)
  60:  {
  61:      std::cout << "setState by Customer " << std::endl;
  62:      m_CustomerState = nState;
  63:  }
  64:  STATE Customer::getState()
  65:  {
  66:      std::cout << "getState by Customer " << std::endl;
  67:      return m_CustomerState;
  68:  }
  69:   
  70:  //AddrVerification 类实现
  71:   
  72:  AddrVerification::~AddrVerification()
  73:  {  
  74:      std::cout << "~AddrVerification() " << std::endl;
  75:  }
  76:  void AddrVerification::update(Customer *pMyCust)
  77:  {
  78:      if(pMyCust == NULL)
  79:          return;
  80:   
  81:      m_ObserverState = pMyCust->getState();
  82:      std::cout << "AddrVerification::update(), m_ObserverState = " 
  83:                << m_ObserverState << std::endl;
  84:   
  85:  }
  86:   
  87:  //WelcomeLetter 类实现
  88:  WelcomeLetter::~WelcomeLetter() 
  89:  { 
  90:      std::cout << "~WelcomeLetter() " << std::endl;
  91:   
  92:  }
  93:  void WelcomeLetter::update(Customer *pMyCust)
  94:  {
  95:      if(pMyCust == NULL)
  96:          return;
  97:   
  98:      m_ObserverState = pMyCust->getState();
  99:      std::cout << "WelcomeLetter::update(), m_ObserverState = " 
 100:          << m_ObserverState << std::endl;
 101:  }
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }
 
//test.cpp
   1:  #include "ObserverSimple.h"
   2:   
   3:  int main()
   4:  {
   5:      //定义一 指向 Customer 的指针
   6:      Customer *myCust = new Customer;
   7:   
   8:      //定义两个不同的指向观察者类 Observer 的子对象指针
   9:      AddrVerification *addr1 = new AddrVerification;
  10:      WelcomeLetter *welcom1 = new WelcomeLetter;
  11:   
  12:      //将 Observer 子类对象 addr1, welcom1 
  13:      //添加到目标观察者列表中, 也称注册
  14:      myCust->attach(addr1);
  15:      myCust->attach(welcom1);
  16:   
  17:      //设置状态, 并观察输出
  18:      myCust->setState(10);
  19:      myCust->notifyObs();
  20:   
  21:      //从目标 Observer 列表中删除给定观察者对象
  22:      //并观察输出
  23:      myCust->detach(addr1);
  24:      myCust->notifyObs();
  25:   
  26:      //改变状态, 观察输出
  27:      myCust->setState(20);
  28:      myCust->notifyObs();
  29:   
  30:      delete myCust;
  31:   
  32:      return EXIT_SUCCESS;
  33:  }
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

通过这种方法可能在不影响任何已有的类的情况下, 添加新的 Observer 类. 它也保持了一切类之间的较松耦合.如果保证所有对象都对自己负责,这种组织方式就可以奏效. 
可以轻松添加一个新类:

有时候,一个要成为观察者的类可能已经存在,这时,可能不希望对其进行修改.如果这样,可以很容易地使用 Adapter模式进行转换.如下图:

clip_image003

   Observer 模式:                关键特征

意图:   在对象之间定义一种一对多的依赖关系, 这样当一个对象的状态改变时,所有依赖者都将得到通知并自动更新

问题:   当某个事件发生时, 需要向一系列变化着的对象发出通知.

解决方案:  Observer 将监视某个事件的责任委托给中心对象: Subject.

参与者与协作者:   Subject 知道自己的 Observer,因为 Observer 要向它注册.Subject 必须在监听的事件发生时通知 Observer. Observer 负责向 Subject 注册,以及在得到通知时从 Subcject 处获得信息.

效果:  如果某些 Observer 只对事件的一个子集感兴趣,那么 Subject 可能会告诉它们不需要知道事件. 如果 Subject 通知 Observer, Observer 还返回请求更多信息,则可能需要额外的通信.

实现:  让某个事件发生时需要知道的对象(Observer)将自己注册到另一个监视事件发生或自己触发的对象 (Subject)上. 事件发生时, Subject 告诉 Observer 事件已经发生. 为了对所有 Observer 类型的对象实现 Observer 接口,有时候需要使用 Adapter 模式.

Observer 的通用结构如下图:

 Observer
实现如下:

//Observer.h

   1:  #pragma once
   2:   
   3:  #include <list>
   4:   
   5:  //状态类型
   6:  typedef int STATE;
   7:   
   8:  class Observer;
   9:   
  10:  // Subject 抽象基类,只需要知道Observer基类的声明就可以了
  11:  class Subject
  12:  {
  13:  public:
  14:      Subject() : m_nSubjectState(-1){}
  15:      virtual ~Subject();
  16:   
  17:      //
  18:      void Notify();                        // 通知对象改变状态
  19:      void Attach(Observer *pObserver);    // 新增对象
  20:      void Detach(Observer *pObserver);    // 删除对象
  21:   
  22:      // 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
  23:      virtual void  SetState(STATE nState);     // 设置状态
  24:      virtual STATE GetState();                 // 得到状态
  25:   
  26:  protected:
  27:      STATE m_nSubjectState;                     // 模拟保存Subject状态的变量
  28:      std::list<Observer*> m_ListObserver;     // 保存Observer指针的链表
  29:  };
  30:   
  31:  // Observer抽象基类
  32:  class Observer
  33:  {
  34:  public:
  35:      Observer() : m_nObserverState(-1){}
  36:      virtual ~Observer(){}
  37:   
  38:      // 纯虚函数,各个派生类可能有不同的实现
  39:      // 通知Observer状态发生了变化
  40:      virtual void Update(Subject* pSubject) = 0;
  41:   
  42:  protected:
  43:      STATE m_nObserverState; // 模拟保存Observer状态的变量
  44:  };
  45:   
  46:  // ConcreateSubject 类,派生在Subject类
  47:  class ConcreateSubject: public Subject
  48:  {
  49:  public:
  50:      ConcreateSubject() : Subject(){    }
  51:      virtual ~ConcreateSubject(){    }
  52:   
  53:      // 派生类自己实现来覆盖基类的实现
  54:      virtual void SetState(STATE nState);    // 设置状态
  55:      virtual STATE GetState();                // 得到状态
  56:  };
  57:   
  58:  // ConcreateObserver类派生自Observer
  59:  class ConcreateObserver: public Observer
  60:  {
  61:  public:
  62:      ConcreateObserver() : Observer(){}
  63:      virtual ~ConcreateObserver(){}
  64:      // 虚函数, 实现基类提供的接口
  65:      virtual void Update(Subject* pSubject);
  66:  };

//Observer.cpp .csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

   1:  #include "Observer.h"
   2:  #include <iostream>
   3:  #include <algorithm>
   4:   
   5:   
   6:  //Subject 类成员函数的实现
   7:  void Subject::Attach(Observer *pObserver)
   8:  {
   9:      std::cout << "Attach an Observer/n";
  10:      m_ListObserver.push_back(pObserver);
  11:  }
  12:  void Subject::Detach(Observer *pObserver)
  13:  {
  14:      std::list<Observer*>::iterator iter;
  15:      iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
  16:      if (m_ListObserver.end() != iter)
  17:      {   delete *iter;  
  18:          m_ListObserver.erase(iter);
  19:      }
  20:      std::cout << "Detach an Observer/n";
  21:  }
  22:  void Subject::Notify()
  23:  {
  24:      std::cout << "Notify Observers's State/n";
  25:      std::list<Observer*>::iterator iter1, iter2;
  26:      for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
  27:          iter1 != iter2;
  28:          ++iter1)
  29:      {
  30:          (*iter1)->Update(this);
  31:      }
  32:  }
  33:  void Subject::SetState(STATE nState)
  34:  {
  35:      std::cout << "SetState By Subject/n";
  36:      m_nSubjectState = nState;
  37:  }
  38:  STATE Subject::GetState()
  39:  {
  40:      std::cout << "GetState By Subject/n";
  41:      return m_nSubjectState;
  42:  }
  43:  Subject::~Subject()
  44:  {
  45:      std::list<Observer*>::iterator iter1, iter2, temp;
  46:      for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
  47:          iter1 != iter2;
  48:          )
  49:      {
  50:          temp = iter1;
  51:          ++iter1;
  52:          delete (*temp);
  53:      }
  54:      m_ListObserver.clear();
  55:  }
  56:   
  57:  //ConcreateSubject类成员函数的实现
  58:  void ConcreateSubject::SetState(STATE nState)
  59:  {
  60:      std::cout << "SetState By ConcreateSubject/n";
  61:      m_nSubjectState = nState;
  62:  }
  63:   
  64:  STATE ConcreateSubject::GetState()
  65:  {
  66:      std::cout << "GetState By ConcreateSubject/n";
  67:      return m_nSubjectState;
  68:  }
  69:   
  70:  //ConcreateObserver类成员函数的实现
  71:  void ConcreateObserver::Update(Subject* pSubject)
  72:  {
  73:      if (NULL == pSubject)
  74:          return;
  75:      m_nObserverState = pSubject->GetState();
  76:      std::cout << "The ObeserverState is " << m_nObserverState << std::endl;
  77:  }
//test.cpp
   1:  #include "Observer.h"
   2:  #include <iostream>
   3:   
   4:  int main()
   5:  {
   6:      Observer *p1 = new ConcreateObserver;
   7:      Observer *p2 = new ConcreateObserver;
   8:      Subject* p = new ConcreateSubject;
   9:   
  10:      p->Attach(p1);
  11:      p->Attach(p2);
  12:   
  13:      p->SetState(4);
  14:      p->Notify();
  15:      
  16:      p->Detach(p1);
  17:      p->SetState(10);
  18:      p->Notify();
  19:   
  20:      delete p;
  21:   
  22:      return EXIT_SUCCESS;
  23:  }
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }
原创粉丝点击