zoukankan      html  css  js  c++  java
  • C++设计模式--观察员

    概要

      在软件构建过程中。我们须要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,全部的依赖对象(观察者对象)都将得到通知。假设这种依赖关系过于紧密,将使软件不能非常好地抵御变化。使用面向对象技术。能够将这种依赖关系弱化,并形成一种稳定的依赖关系。

    从而实现软件体系结构的松耦合。

         意图

      定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 全部依赖于它的对象都得到通知并被自己主动更新。[GOF 《设计模式》]

            特点:
            1、  Subject和Observer之间是松偶合的,分别能够各自独立改变。


            2、  Subject在发送广播通知的时候,无须指定详细的Observer。Observer能够自己决定是否要订阅Subject的通知。
            3、  遵守大部分GRASP原则和经常使用设计原则,高内聚、低偶合。


            应用场景:
            1、  对一个对象状态的更新,须要其它对象同步更新,并且其它对象的数量动态可变。
            2、  对象仅须要将自己的更新通知给其它对象而不须要知道其它对象的细节。

            UML图

           

              代码实现

    1. #pragma once  
    2. #include <string>  
    3. #include <list>  
    4. #include "Define.h"  
    5.   
    6. class IObserver;  
    7. class ISubject  
    8. {  
    9. public:  
    10.     ISubject(void);  
    11.     virtual ~ISubject(void);  
    12.   
    13.     virtual int Attach(IObserver* pObs) = 0;  
    14.   
    15.     virtual int Detach(IObserver* pObs) = 0;  
    16.   
    17.     virtual int Notify() = 0;  
    18.   
    19.     virtual State GetState() = 0;  
    20.   
    21.     virtual void SetState(const State& state) = 0;  
    22.   
    23. protected:  
    24.     typedef std::list<IObserver*> L_OBS;  
    25.     L_OBS   m_obsArray;  
    26. };  
    1. #pragma once  
    2. #include "ISubject.h"  
    3.   
    4. class CSubjectA : public ISubject  
    5. {  
    6. public:  
    7.     CSubjectA(void);  
    8.     virtual ~CSubjectA(void);  
    9.   
    10.     virtual int Attach(IObserver* pObs);  
    11.   
    12.     virtual int Detach(IObserver* pObs);  
    13.   
    14.     virtual int Notify();  
    15.   
    16.     virtual State GetState();  
    17.   
    18.     virtual void SetState(const State& state);  
    19.   
    20. private:  
    21.   
    22.     State m_state;  
    23. };  
    1. #include "CSubjectA.h"  
    2. #include "IObserver.h"  
    3.   
    4. CSubjectA::CSubjectA(void)  
    5. {  
    6. }  
    7.   
    8. CSubjectA::~CSubjectA(void)  
    9. {  
    10.     if (!m_obsArray.empty())  
    11.     {  
    12.         m_obsArray.clear();  
    13.         L_OBS().swap(m_obsArray);  
    14.     }  
    15. }  
    16.   
    17. int CSubjectA::Attach( IObserver* pObs )  
    18. {  
    19.     m_obsArray.push_back(pObs);  
    20.   
    21.     return 0;  
    22. }  
    23.   
    24. int CSubjectA::Detach( IObserver* pObs )  
    25. {  
    26.     m_obsArray.remove(pObs);  
    27.   
    28.     return 0;  
    29. }  
    30.   
    31. int CSubjectA::Notify()  
    32. {  
    33.     L_OBS::iterator it_beg, it_end=m_obsArray.end();  
    34.     for (it_beg=m_obsArray.begin(); it_beg!=it_end; ++it_beg)  
    35.     {  
    36.         (*it_beg)->Update();  
    37.     }  
    38.   
    39.     return 0;  
    40. }  
    41.   
    42. State CSubjectA::GetState()  
    43. {  
    44.     return m_state;  
    45. }  
    46.   
    47. void CSubjectA::SetState( const State& state )  
    48. {  
    49.     m_state = state;  
    50. }  
    1. #pragma once  
    2. #include "Define.h"  
    3.   
    4. class IObserver  
    5. {  
    6. public:  
    7.     IObserver(void);  
    8.     virtual ~IObserver(void);  
    9.   
    10.     virtual int Update() = 0;  
    11. };  
    1. #pragma once  
    2. #include "IObserver.h"  
    3.   
    4. class ISubject;  
    5. class CObserveA : public IObserver  
    6. {  
    7. public:  
    8.     CObserveA(ISubject* pSubject);  
    9.     virtual ~CObserveA(void);  
    10.   
    11.     virtual int Update();  
    12.   
    13. private:  
    14.     ISubject* m_pSubject;  
    15. };  
    1. #include "CObserveA.h"  
    2. #include <cstdio>  
    3. #include "ISubject.h"  
    4.   
    5. CObserveA::CObserveA(ISubject* pSubject)  
    6.     :m_pSubject(pSubject)  
    7. {  
    8.     m_pSubject->Attach(this);  
    9. }  
    10.   
    11. CObserveA::~CObserveA(void)  
    12. {  
    13.     m_pSubject->Detach(this);  
    14. }  
    15.   
    16. int CObserveA::Update()  
    17. {  
    18.     State str = m_pSubject->GetState();  
    19.   
    20.     printf("first get: [%s] ", str.c_str());  
    21.     return 0;  
    22. }  
    1. #include "CSubjectA.h"  
    2. #include "CObserveA.h"  
    3.   
    4. int main()  
    5. {  
    6.     CSubjectA subA;  
    7.     CObserveA first(&subA);  
    8.   
    9.     subA.SetState("test set state");  
    10.   
    11.     subA.Notify();  
    12.   
    13.     return 0;  
    14. }  

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    千千静听被拖到桌面之外的解决办法
    Excel学习(二)快速添充单元格
    tomcat中的server.xml中关于虚拟目录的设定
    配置SVN
    DataTable.Select() 方法的简单用法
    Excel学习(一) 单元格显示下拉列表框
    Excel学习(三)添加打印预览按钮
    打造自己的资料库
    APAHCE基于IP端口的虚拟主机的设定
    反射
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4640484.html
Copyright © 2011-2022 走看看