• C++设计模式-Observer观察者模式


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

    UML图:


    Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个借口实现。它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个借口,可以增加和删除观察者对象。

    Observer类,抽象观察者,为所有的具体观察者定义一个借口,在得到主题的通知时更新自己。这个借口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个Update()方法。

    ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体通知者对象;在具体主题的内部状态改变时,给所有等级过的观察者发出通知。通常用一个具体子类实现。

    ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向一个具体主题对象的引用。

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

    何时使用:
    当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
    观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

    代码如下:

    Observer.h

     1 #ifndef _OBSERVER_H_
     2 #define _OBSERVER_H_
     3 
     4 #include <string>
     5 #include <list>
     6 using namespace std;
     7 
     8 class Subject;
     9 
    10 class Observer
    11 {
    12 public:
    13     ~Observer();
    14     virtual void Update(Subject*)=0;
    15 protected:
    16     Observer();
    17 private:
    18 };
    19 
    20 class ConcreteObserverA : public Observer
    21 {
    22 public:
    23     ConcreteObserverA();
    24     ~ConcreteObserverA();
    25     virtual void Update(Subject*);
    26 protected:
    27 private:
    28     string m_state;
    29 };
    30 
    31 class ConcreteObserverB : public Observer
    32 {
    33 public:
    34     ConcreteObserverB();
    35     ~ConcreteObserverB();
    36     virtual void Update(Subject*);
    37 protected:
    38 private:
    39     string m_state;
    40 };
    41 
    42 class Subject
    43 {
    44 public:
    45     ~Subject();
    46     virtual void Notify();
    47     virtual void Attach(Observer*);
    48     virtual void Detach(Observer*);
    49     virtual string GetState();
    50     virtual void SetState(string state);
    51 protected:
    52     Subject();
    53 private:
    54     string m_state;
    55     list<Observer*> m_lst;
    56 };
    57 
    58 class ConcreteSubjectA : public Subject
    59 {
    60 public:
    61     ConcreteSubjectA();
    62     ~ConcreteSubjectA();
    63 protected:
    64 private:
    65 };
    66 
    67 class ConcreteSubjectB : public Subject
    68 {
    69 public:
    70     ConcreteSubjectB();
    71     ~ConcreteSubjectB();
    72 protected:
    73 private:
    74 };
    75 
    76 #endif

    Observer.cpp

     1 #include "Observer.h"
     2 #include <iostream>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 Observer::Observer()
     8 {}
     9 
    10 Observer::~Observer()
    11 {}
    12 
    13 ConcreteObserverA::ConcreteObserverA()
    14 {}
    15 
    16 ConcreteObserverA::~ConcreteObserverA()
    17 {}
    18 
    19 void ConcreteObserverA::Update(Subject* pSubject)
    20 {
    21     this->m_state = pSubject->GetState();
    22     cout << "The ConcreteObserverA is " << m_state << std::endl;
    23 }
    24 
    25 ConcreteObserverB::ConcreteObserverB()
    26 {}
    27 
    28 ConcreteObserverB::~ConcreteObserverB()
    29 {}
    30 
    31 void ConcreteObserverB::Update(Subject* pSubject)
    32 {
    33     this->m_state = pSubject->GetState();
    34     cout << "The ConcreteObserverB is " << m_state << std::endl;
    35 }
    36 
    37 Subject::Subject()
    38 {}
    39 
    40 Subject::~Subject()
    41 {}
    42 
    43 void Subject::Attach(Observer* pObserver)
    44 {
    45     this->m_lst.push_back(pObserver);
    46     cout << "Attach an Observer
    ";
    47 }
    48 
    49 void Subject::Detach(Observer* pObserver)
    50 {
    51     list<Observer*>::iterator iter;
    52     iter = find(m_lst.begin(),m_lst.end(),pObserver);
    53     if(iter != m_lst.end())
    54     {
    55         m_lst.erase(iter);
    56     }
    57     cout << "Detach an Observer
    ";
    58 }
    59 
    60 void Subject::Notify()
    61 {
    62     list<Observer*>::iterator iter = this->m_lst.begin();
    63     for(;iter != m_lst.end();iter++)
    64     {
    65         (*iter)->Update(this);
    66     }
    67 }
    68 
    69 string Subject::GetState()
    70 {
    71     return this->m_state;
    72 }
    73 
    74 void Subject::SetState(string state)
    75 {
    76     this->m_state = state;
    77 }
    78 
    79 ConcreteSubjectA::ConcreteSubjectA()
    80 {}
    81 
    82 ConcreteSubjectA::~ConcreteSubjectA()
    83 {}
    84 
    85 ConcreteSubjectB::ConcreteSubjectB()
    86 {}
    87 
    88 ConcreteSubjectB::~ConcreteSubjectB()
    89 {}

    main.cpp

    #include "Observer.h"
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        Observer* p1 = new ConcreteObserverA();
        Observer* p2 = new ConcreteObserverB();
        Observer* p3 = new ConcreteObserverA();
    
        Subject* pSubject = new ConcreteSubjectA();
        pSubject->Attach(p1);
        pSubject->Attach(p2);
        pSubject->Attach(p3);
    
        pSubject->SetState("old");
    
        pSubject->Notify();
    
        cout << "-------------------------------------" << endl;
        pSubject->SetState("new");
    
        pSubject->Detach(p3);
        pSubject->Notify();
    
        return 0;
    }

    结果如下:

  • 相关阅读:
    【Redis过期Key监听】
    【ElasticSearch】ES线上脏数据处理
    【MySQL】实现线上千万数据表添加字段操作以及缓存刷新
    【转】【堆外内存】堆内内存与堆外内存
    【Redis连接超时】记录线上RedisConnectionFailureException异常排查过程
    【ElasticSearch】ES 读数据,写数据与搜索数据的过程
    【ElasticSearch】shards,replica,index之间的关系
    tomorrow多线程启动
    request接口下载附件
    request接口上传附件
  • 原文地址:https://www.cnblogs.com/jiese/p/3183635.html
Copyright © 2020-2023  润新知