• 行为型模式:Observer——观察者模式


    1、意图

    定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。

    2、核心思想

         观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

    使用动机:

      将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。

    本模式适用情况:

    (1)当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。

    (2)当一个抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。

    总结:

    观察者模式所做的工作其实就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

    本模式是依赖倒置原则的最佳体现!

    设计原则:为了交互对象之间的松耦合设计而奋斗到底!

    3、优缺点分析

    GOOD:

    定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。

    BAD:

    尽管使用了“依赖倒置原则”,但是“抽象通知者”还是依赖于“抽象观察者”。而且每个具体观察者不一定是“更新”方法需要调用。

    在.net中可通过事件委托方法,使得通知者和观察者之间根本就互相不知道。 

    4、标准UML图

    clip_image002

    解析:

        Observer模式定义的是一种一对多的关系,一是指Subject类对象,多则是Observer类对象。当Subject类对象的状态发生变化的时候通知与之对应的Observer类对象们也去相应的更新状态,同时支持动态的添加和删除Observer对象的功能。

    Observer模式的实现要点是:

    (一)一般Subject类都是采用链表等容器来存放Observer对象

    (二)抽取出Observer对象的一些公共属性形成Observer基类,而Subject类中保存的则是Observer类对象的指针(从而实现了Subject和具体的Observer解耦

    5、标准源码

       1: /************************************************************************
       2:  * FileName    : Observer.h
       3:  * Author      : steven oyj (steven.oyj@gmail.com)
       4:  * Description : Observer模式的演示代码
       5:  * Time        : 2010/5/21
       6:  ************************************************************************/
       7: #ifndef OBSERVER_H
       8: #define OBSERVER_H
       9:  
      10: #include <list>
      11:  
      12: typedef int STATE;
      13:  
      14: class Observer;
      15:  
      16: // Subject抽象基类,只需要知道Observer基类的声明就可以了
      17: class Subject
      18: {
      19: public:
      20:     Subject() : m_nSubjectState(-1){}
      21:     virtual ~Subject();
      22:  
      23:     void Notify();                            // 通知对象改变状态
      24:     void Attach(Observer *pObserver);        // 新增对象
      25:     void Detach(Observer *pObserver);        // 删除对象
      26:  
      27:     // 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
      28:     virtual void    SetState(STATE nState);    // 设置状态
      29:     virtual STATE    GetState();                // 得到状态
      30:  
      31: protected:
      32:     STATE m_nSubjectState;                    // 模拟保存Subject状态的变量
      33:     std::list<Observer*>    m_ListObserver;    // 保存Observer指针的链表
      34: };
      35:  
      36: // Observer抽象基类
      37: class Observer
      38: {
      39: public:
      40:     Observer() : m_nObserverState(-1){}
      41:     virtual ~Observer(){}
      42:  
      43:     // 纯虚函数,各个派生类可能有不同的实现
      44:     // 通知Observer状态发生了变化
      45:     virtual void Update(Subject* pSubject) = 0;
      46:  
      47: protected:
      48:     STATE m_nObserverState;                    // 模拟保存Observer状态的变量
      49: };
      50:  
      51: // ConcreateSubject类,派生在Subject类
      52: class ConcreateSubject
      53:     : public Subject
      54: {
      55: public:
      56:     ConcreateSubject() : Subject(){}
      57:     virtual ~ConcreateSubject(){}
      58:  
      59:     // 派生类自己实现来覆盖基类的实现
      60:     virtual void    SetState(STATE nState);    // 设置状态
      61:     virtual STATE    GetState();        // 得到状态
      62:  
      63: };
      64:  
      65: // ConcreateObserver类派生自Observer
      66: class ConcreateObserver
      67:     : public Observer
      68: {
      69: public:
      70:     ConcreateObserver() : Observer(){}
      71:     virtual ~ConcreateObserver(){}
      72:  
      73:     // 虚函数,实现基类提供的接口
      74:     virtual void Update(Subject* pSubject);
      75: };
      76:  
      77: #endif
       1: /************************************************************************
       2:  * FileName    : Observer.cpp
       3:  * Author      : steven oyj (steven.oyj@gmail.com)
       4:  * Description : Observer模式的演示代码
       5:  * Time        : 2010/5/21
       6:  ************************************************************************/
       7: #include "Observer.h"
       8: #include <iostream>
       9: #include <algorithm>
      10:  
      11: /* --------------------------------------------------------------------
      12: |    Subject类成员函数的实现
      13: |
      14:  ----------------------------------------------------------------------*/
      15:  
      16: void Subject::Attach(Observer *pObserver)
      17: {
      18:     std::cout << "Attach an Observer\n";
      19:  
      20:     m_ListObserver.push_back(pObserver);
      21: }
      22:  
      23: void Subject::Detach(Observer *pObserver)
      24: {
      25:     std::list<Observer*>::iterator iter;
      26:     iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
      27:  
      28:     if (m_ListObserver.end() != iter)
      29:     {
      30:         m_ListObserver.erase(iter);
      31:     }
      32:  
      33:     std::cout << "Detach an Observer\n";
      34: }
      35:  
      36: void Subject::Notify()
      37: {
      38:     std::cout << "Notify Observers's State\n";
      39:  
      40:     std::list<Observer*>::iterator iter1, iter2;
      41:  
      42:     for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
      43:          iter1 != iter2;
      44:          ++iter1)
      45:     {
      46:         (*iter1)->Update(this);
      47:     }
      48: }
      49:  
      50: void Subject::SetState(STATE nState)
      51: {
      52:     std::cout << "SetState By Subject\n";
      53:     m_nSubjectState = nState;
      54: }
      55:  
      56: STATE Subject::GetState()
      57: {
      58:     std::cout << "GetState By Subject\n";
      59:     return m_nSubjectState;
      60: }
      61:  
      62: Subject::~Subject()
      63: {
      64:     std::list<Observer*>::iterator iter1, iter2, temp;
      65:  
      66:     for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
      67:         iter1 != iter2;
      68:         )
      69:     {
      70:         temp = iter1;
      71:         ++iter1;
      72:         delete (*temp);
      73:     }
      74:  
      75:     m_ListObserver.clear();
      76: }
      77:  
      78: /* --------------------------------------------------------------------
      79: |    ConcreateSubject类成员函数的实现
      80: |
      81: ----------------------------------------------------------------------*/
      82: void ConcreateSubject::SetState(STATE nState)
      83: {
      84:     std::cout << "SetState By ConcreateSubject\n";
      85:     m_nSubjectState = nState;
      86: }
      87:  
      88: STATE ConcreateSubject::GetState()
      89: {
      90:     std::cout << "GetState By ConcreateSubject\n";
      91:     return m_nSubjectState;
      92: }
      93:  
      94: /* --------------------------------------------------------------------
      95: |    ConcreateObserver类成员函数的实现
      96: |
      97: ----------------------------------------------------------------------*/
      98: void ConcreateObserver::Update(Subject* pSubject)
      99: {
     100:     if (NULL == pSubject)
     101:         return;
     102:  
     103:     m_nObserverState = pSubject->GetState();
     104:  
     105:     std::cout << "The ObeserverState is " << m_nObserverState << std::endl;
     106: }
       1: /************************************************************************
       2:  * FileName    : Main.cpp
       3:  * Author      : steven oyj (steven.oyj@gmail.com)
       4:  * Description : Observer模式的测试代码
       5:  * Time        : 2010/5/21
       6:  ************************************************************************/
       7: #include "Observer.h"
       8: #include <iostream>
       9:  
      10: int main()
      11: {
      12:     Observer *p1 = new ConcreateObserver;
      13:     Observer *p2 = new ConcreateObserver;
      14:  
      15:     Subject* p = new ConcreateSubject;
      16:     p->Attach(p1);
      17:     p->Attach(p2);
      18:     p->SetState(4);
      19:     p->Notify();
      20:  
      21:     p->Detach(p1);
      22:     p->SetState(10);
      23:     p->Notify();
      24:  
      25:     delete p;
      26:  
      27:     system("pause");
      28:  
      29:     return 0;
      30: }
  • 相关阅读:
    如何安装ArchLinux
    状态模式
    iOS设备的越狱方法
    浅析Windows安全相关的一些概念
    项目做成jar包
    JavaScript包装对象
    node.js系列笔记之node.js初识《一》
    使用Reactive Extensions(Rx),对短时间内多次发生的事件限流
    in和exists哪个效率高本人测试证明
    Asp.net MVC使用Filter解除Session, Cookie等依赖
  • 原文地址:https://www.cnblogs.com/steven_oyj/p/1749745.html
Copyright © 2020-2023  润新知