Bootstrap

【嵌入式c++】设计模式之观察者模式(Observer)

Observer

动机(Motivation)

  • 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对
    象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

模式定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
——《 设计模式》 GoF

要点总结

  • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
  • 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
  • Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。

代码结构

.
├── build.sh
├── clearBuild.sh
├── CMakeLists.txt
├── src 
│   ├── examStu.cpp
│   ├── include
│   │   └── examStu.h
│   └── main.cpp

源码例子1 (定时器)

examStu.h

#ifndef _EXANSTU__
#define _EXANSTU__

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

//Observer 
class TimerObserver
{
public:
    TimerObserver()=default;
    virtual ~TimerObserver(){};   

    virtual void OnTime(int value) = 0;
    
   
private:

};

//object
class Timer
{
public:
    Timer()=default;
    virtual ~Timer(){};

    virtual void Notify() = 0;
    virtual void AddObserver(TimerObserver*) = 0;
    virtual void Detach(TimerObserver* )=0;

private:

};



class ShopingTimerObserver:public TimerObserver
{
public:
    ShopingTimerObserver()=default;
    ShopingTimerObserver(Timer* pTimer):m_pTimer(pTimer){}
    ~ShopingTimerObserver(){};   


    void OnTime(int value) 
    {
        cout << "update Shoping state:" << value <<endl;      
    }

private:
    Timer * m_pTimer;

};


class CookkingTimerObserver:public TimerObserver
{
public:
    CookkingTimerObserver()=default;
    CookkingTimerObserver(Timer* pTimer):m_pTimer(pTimer){}

    ~CookkingTimerObserver(){};   


    void OnTime(int value) override
    {
        cout << "update Cookking state:" << value <<endl;      
    }

private:

    Timer * m_pTimer;
};



class ConcreteTimer : public Timer
{
public:
    ConcreteTimer():m_State(0){}
    ~ConcreteTimer(){};

    void AddObserver(TimerObserver* pTimerObserver)
    {
        m_pTimerObserverList.push_back(pTimerObserver);
    }   
    void Detach(TimerObserver* pTimerObserver)
    {
        m_pTimerObserverList.remove(pTimerObserver);
    }

    void Notify()
    {
        std::list<TimerObserver *>::iterator it = m_pTimerObserverList.begin();
        while (it != m_pTimerObserverList.end())
        {
            (*it)->OnTime(m_State);
            ++it;
        }        
    }

    void SetState(int state)
    {
        m_State = state;
    }

private:    
    std::list<TimerObserver *> m_pTimerObserverList;   
    int m_State;
};

#endif

main.cpp

#include <iostream>
#include <string>
#include <memory>

#include "examStu.h"

using namespace std;


int main()
{
    ConcreteTimer* pConcreteTimer = new ConcreteTimer();

    TimerObserver* pShopingTimerObserver = new ShopingTimerObserver(pConcreteTimer);
    TimerObserver* pCookkingTimerObserver = new CookkingTimerObserver(pConcreteTimer);


    pConcreteTimer->AddObserver(pShopingTimerObserver);
    pConcreteTimer->AddObserver(pCookkingTimerObserver);


    pConcreteTimer->SetState(2);
    pConcreteTimer->Notify();


    // Unregister the observer
    pConcreteTimer->Detach(pShopingTimerObserver);
 
    pConcreteTimer->SetState(3);
    pConcreteTimer->Notify();
 
    delete pConcreteTimer;
    delete pShopingTimerObserver;
    delete pCookkingTimerObserver;


    return 0;
}

源码例子2

examStu.h

#ifndef _EXANSTU__
#define _EXANSTU__

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

 
class Observer
{
public:
    virtual void Update(int) = 0;
};
 
class Subject  //timer
{
public:
    virtual void Attach(Observer *) = 0;
    virtual void Detach(Observer *) = 0;
    virtual void Notify() = 0;
};
 
class ConcreteObserver1 : public Observer
{
public:
    ConcreteObserver1(Subject *pSubject) : m_pSubject(pSubject){}
 
    void Update(int value)
    {
        cout << "ConcreteObserver1 get the update. New State:" << value << endl;
    }
 
private:
    Subject *m_pSubject;
};
 
class ConcreteObserver2 : public Observer
{
public:
    ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
 
    void Update(int value)
    {
        cout << "ConcreteObserver2 get the update. New State:" << value << endl;
    }
 
private:
    Subject *m_pSubject;
};
 
class ConcreteSubject : public Subject
{
public:
    void Attach(Observer *pObserver)
    {
        m_ObserverList.push_back(pObserver);
    }
    void Detach(Observer *pObserver)
    {
        m_ObserverList.remove(pObserver);
    }

    void Notify()
    {
        std::list<Observer *>::iterator it = m_ObserverList.begin();
        while (it != m_ObserverList.end())
        {
            (*it)->Update(m_iState);
            ++it;
        }        
    }
 
    void SetState(int state)
    {
        m_iState = state;
    }
 
private:
    std::list<Observer *> m_ObserverList;
    int m_iState;
};

#endif

main.cpp

#include <iostream>
#include <string>
#include <memory>

#include "examStu.h"

using namespace std;


int main(int argc, char *argv[])
{
    // Create Subject
    ConcreteSubject *pSubject = new ConcreteSubject();
 
    // Create Observer
    Observer *pObserver1 = new ConcreteObserver1(pSubject);
    Observer *pObserver2 = new ConcreteObserver2(pSubject);
 
    // Change the state
    pSubject->SetState(2);
 
    // Register the observer
    pSubject->Attach(pObserver1);
    pSubject->Attach(pObserver2);
 
    pSubject->Notify();
 
    // Unregister the observer
    pSubject->Detach(pObserver1);
 
    pSubject->SetState(3);
    pSubject->Notify();
 
    delete pObserver1;
    delete pObserver2;
    delete pSubject;
    return 0;
}
;