C++實現設計模式:Observer Pattern

This example demonstrates creating three separate observer classes and subscribes them for different combinations of the two messages defined by the MySubject class. Finally, the calls to subject.Notify() cause the subject to traverse its list of observers that have been subscribed for the given message and calls the Update() method for each of them.

//obserer.h
#include <iostream>
#include <string>

class IObserver
{
public:
    virtual ~IObserver(){}
    virtual void Update(int message)=0;
};

class MyObserver:public IObserver
{
public:
    explicit MyObserver(const std::string& str):mName(str)
    {}

    void Update(int message)
    {
        std::cout<<mName<<" Received message "<<message<<std::endl;
    }

private:
    std::string mName;
};


//subject.h
#include "obserer.h"
#include <map>
#include <vector>

class ISubject
{
public:
    typedef std::vector<IObserver*> ObserverList;
    typedef std::vector<IObserver*>::iterator iter_ObserverList;

    typedef std::map<int, ObserverList> ObserverMap;
    typedef std::map<int, ObserverList>::iterator iter_ObserverMap;

    ISubject(){}

    virtual ~ISubject()=0
    {
        //
    }

    virtual void Subscribe(int message, IObserver* observer);
    virtual void Unsubscribe(int message, IObserver* observer);
    virtual void Notify(int message);

private:  
    ObserverMap mObservers;
};

class MySubject:public ISubject
{
public:
    enum Message{ ADD, REMOVE};
    MySubject()
    {
        //
    }

    ~MySubject()
    {
        //
    }
};



//subject.cpp
#include "subject.h"

void ISubject::Subscribe(int message, IObserver* observer)
{
    iter_ObserverMap iter = mObservers.find(message);
    
    if(iter!=mObservers.end())
    {
        iter->second.push_back(observer);
    }
    else
    {
        ObserverList list;
        list.push_back(observer);
        mObservers.insert(std::pair<int, ObserverList>(message, list));
    }
}

void ISubject::Unsubscribe(int message, IObserver* observer)
{
    iter_ObserverMap iter_map = mObservers.find(message);
    if(iter_map!=mObservers.end())
    {
        for(iter_ObserverList iter_list=iter_map->second.begin(); iter_list!=iter_map->second.end(); ++iter_list)
        {
            if((*iter_list) == observer)
            {
                iter_map->second.erase(iter_list);
            }
        }
    }
}

void ISubject::Notify(int message)
{
    iter_ObserverMap iter_map = mObservers.find(message);
    if(iter_map!=mObservers.end())
    {
        for(iter_ObserverList iter_list=iter_map->second.begin(); iter_list!=iter_map->second.end(); ++iter_list)
        {
            (*iter_list)->Update(message);
        }
    }
}


#include <iostream>
#include "subject.h"

int main()
{
    MyObserver observer1("observer1");
    MyObserver observer2("observer2");
    MyObserver observer3("observer3");
    
    MySubject subject;

    subject.Subscribe(MySubject::ADD, &observer1);
    subject.Subscribe(MySubject::ADD, &observer2);
    subject.Subscribe(MySubject::REMOVE, &observer2);
    subject.Subscribe(MySubject::REMOVE, &observer3);

    subject.Notify(MySubject::ADD);
    subject.Notify(MySubject::REMOVE);
    //
    system("PAUSE");
}

Running result:





The important point to note is that the MySubject class has no compile-time dependency on the MyObserver class. The relationship between the two classes is dynamically created at run time.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章