Observer Pattern with C++

观察者模式C++实现

观察者模式是非常重要的一个模式,初次遇到该模式,想了很久没有想通应该怎么做。

其实原理很简单:就是当被观察者(Observable)发生变化,然后就会某种数据方式通知(Notify)观察者(Observer),Notify的方式很多,比如我们将Observer 放到一个list或者set中,分别调用Observer的update()这样实现通知。

这个模式和之前的责任链模式很相似,不同的是观察者模式在消息传播的时候,消息是可变的。责任链模式在消息 传播的过程保持消息的不可变。

####另外我们要说明的是ObserverPattern模式中最好只出现一个既是Observer又是Observable的对象,消息最多转发一次

####从效率上来说,如果一个Observer被阻塞,会影响其他Observer的Notify(),所以Notify()最好采用异步的方式。不过异步的话就要考虑线程安全和队列的问题,需要查看message queue。

下面是UML类图


#include 
#include 
#include 
using namespace std;
 
class IObserver
{
public:
    IObserver(string _name)
    {
        this->m_name = _name;
    }
    virtual ~IObserver(void)
    {
    }
    virtual void Update(string context) = 0;
    virtual string GetName() = 0;//为c++单独增加的函数,用于删除时查找观察者。
protected:
    string m_name;
};
 
class IObservable
{
public:
    IObservable(void)
    {
    }
    virtual ~IObservable(void)
    {
    }
    virtual void AddObserver(IObserver *pObserver) = 0;
    virtual void DeleteObserver(IObserver *pObserver) = 0;
    virtual void NotifyObservers(string context) = 0;
};
 
class SuperStar : public IObservable
{
public:
    SuperStar(void){}
    ~SuperStar(void){}
    void AddObserver(IObserver *pObserver){m_observerList.push_back(pObserver);}
    void DeleteObserver(IObserver *pObserver)
    {
        ObserverList_C_iterator it = m_observerList.begin();
        for (; it != m_observerList.end(); it++)
        {
            string name = (*it)->GetName();
            if (name.compare(pObserver->GetName()) == 0)
            {
                it = m_observerList.erase(it);
            }
        }
    }
    void NotifyObservers(string context)
    {
        ObserverList_C_iterator it = m_observerList.begin();
        for (; it != m_observerList.end(); it ++)
        {
            (*it)->Update(context);
        }
    }
    void HaveBreakfast()
    {
         cout << "SuperStart begin to have breakfast..." << endl;
         this->NotifyObservers("SuperStart begin to have breakfast");
    }
    void HaveFun()
    {
         cout << "SuperStart begin to have fun..." << endl;
         this->NotifyObservers("SuperStart begin to have fun");
    }
private:
    vector<IObserver*> m_observerList;
    typedef vector<IObserver*>::const_iterator ObserverList_C_iterator;
};
class Spy1 :  public IObserver
{
public:
    Spy1(void):IObserver("SPY1"){}
    ~Spy1(void){}
    void Update(string context)
    {
        cout << "Spy1:something happened..." << endl;
        this->ReportToBoss(context);
        cout << "Spy1:get some price" << endl;
    }
    string GetName(){return m_name;}
private:
    void ReportToBoss(string report)
    {
         cout << "Spy1:Boss->" << report.c_str() << endl;
    }
};
class Spy2 :  public IObserver
{
public:
    Spy2(void):IObserver("SPY1"){}
    ~Spy2(void){}
    void Update(string context)
    {
        cout << "Spy2:something happened..." << endl;
        this->ReportToBoss(context);
        cout << "Spy2:get some price" << endl;
    }
    string GetName(){return m_name;}
private:
    void ReportToBoss(string report)
    {
         cout << "Spy2:Boss->" << report.c_str() << endl;
    }
};
 
int main()
{
    IObserver *spy1 = new Spy1();
    IObserver *spy2 = new Spy2();
 
    SuperStar *superstar = new SuperStar();
 
    superstar->AddObserver(spy1);
    superstar->AddObserver(spy2);
 
    superstar->HaveFun();
 
    cout << endl;
    superstar->DeleteObserver(spy1);
    superstar->HaveBreakfast();
 
    delete spy1;
    spy1 = NULL;
    delete spy2;
    spy2 = NULL;
}
</code></pre>

因为是C++实现,没有通用的Observer Pattern framework,所以我们在class superstar中实现了

void AddObserver(IObserver *pObserver)

void DeleteObserver(IObserver *pObserver)

void NotifyObservers(string context)

如果我们把这个代码变为一种framework,类图会变化
![](/assets/pic/Observer2.png)