• 观察者模式


    一、简介
    1. 概念
    GOF的《设计模式》这样定义观察模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化,关注它的对象就会得到通知;这种交互也称为发布-订阅(publish-subscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者。
    2. 目的
    解决多个对象同时关系一个实体的变更状态的问题。
    3. 优点
    1)运行时我们变更观察者,被观察对象不会受到影响;
    2)可以动态添加观察者;
    3)改变被观察者或者观察者的任何一方都不会影响另一方。
    二、结构类图

    三、代码示例

      1 #ifndef Observe_h
      2 #define Observe_h
      3 
      4 using namespace std;
      5 
      6 class ConfigObserverMgr;
      7 
      8 class IObserver
      9 {
     10 public:
     11     IObserver();
     12     virtual ~IObserver() {};
     13 
     14     virtual int            update() = 0;
     15 private:
     16 
     17 };
     18 
     19 class Config1Observer : public IObserver
     20 {
     21 public:
     22     Config1Observer();
     23     virtual ~Config1Observer() {};
     24 
     25     virtual int update()
     26     {
     27         //todo
     28     };
     29 
     30 };
     31 
     32 class Config2Observer : public IObserver
     33 {
     34 public:
     35     Config2Observer();
     36     virtual ~Config2Observer();
     37 
     38     virtual int update()
     39     {
     40         //todo
     41     };
     42 
     43 };
     44 
     45 class ConfigObserverMgr
     46 {
     47 public:
     48     ConfigObserverMgr();
     49     virtual ~ConfigObserverMgr() {};
     50 
     51     void registerObserver(IObserver* observer)
     52     {
     53         if (!m_observerList.contains(observer))
     54         {
     55             m_observerList.append(observer);
     56         }
     57     };
     58     void unregisterObserver(IObserver* observer)
     59     {
     60         if (!m_observerList.contains(observer))
     61         {
     62             m_observerList.removeOne(observer);
     63         }
     64     };
     65     void notifyUpdate()
     66     {
     67         for (auto observer : m_observerList)
     68         {
     69             observer->update();
     70         }
     71     };
     72 private:
     73     QList<IObserver*>        m_observerList;
     74 };
     75 
     76 class ISubject
     77 {
     78 public:
     79     ISubject(ConfigObserverMgr* mgr)
     80         :m_observerMgr(mgr)
     81     {};
     82     virtual ~ISubject() {};
     83 
     84     virtual void stateChanged();
     85     
     86     void addObserver(IObserver *observer)
     87     {
     88         m_observerMgr->registerObserver(observer);
     89     };
     90 
     91     void removeObserver(IObserver *oberser)
     92     {
     93         m_observerMgr->unregisterObserver(oberser);
     94     };
     95 
     96     void notify()
     97     {
     98         if (nullptr != m_observerMgr)
     99         {
    100             m_observerMgr->notifyUpdate();
    101         }
    102     };
    103 protected:
    104     ConfigObserverMgr        *m_observerMgr;
    105 };
    106 
    107 class ConfigSubject : public ISubject
    108 {
    109     ConfigSubject(ConfigObserverMgr* mgr)
    110         : ISubject(mgr)
    111     {};
    112     virtual ~ConfigSubject() {};
    113 
    114     void stateChanged()
    115     {
    116         notify();
    117 };
    118 
    119 void main()
    120 {
    121     ConfigObserverMgr *mgr = new ConfigObserverMgr; // 创建一个观察者管理者
    122     ConfigSubject *subject = new ConfigSubject(mgr);// 创建被观察的实体 
    123 
    124     Config1Observer *config1 = new Config1Observer; // 创建观察者1
    125     Config2Observer *config2 = new Config2Observer; // 创建观察者2
    126 
    127     // 注册观察者
    128     subject->addObserver(config1);
    129     subject->addObserver(config2);
    130 
    131     subject->stateChanged();    // 状态变更,通知各个观察者
    132 };
    133 
    134 #endif // !Observe_h

      借鉴实际使用中的一些经验,本例中在原有的观察者模式中,抽取了一个观察者管理者,可以更加便利的管理观察的注销、注册与通知。

      以上为现阶段的学习总结,后续如有新的理解,会及时更新。

  • 相关阅读:
    父级设置display:flex;子级宽度无效的解决办法
    小程序注意事项
    css 字体默认有高度 怎么去掉
    小程序长按识别问题
    css 列表多列多行 同行等高样式
    AndroidManifest.xml:90: error: Error: String types not allowed (at 'largeHeap' with value 'auto').
    10.4.2 ListView.ScrollViewChange存在的问题
    【转】UniTreeMenu控件不显示滚动条的解决办法
    Delphi 10.4.2拍照遇到的新问题
    ChinaCock 用CCShortcutBadger组件显示角标
  • 原文地址:https://www.cnblogs.com/yuemw/p/10125993.html
Copyright © 2020-2023  润新知