設計模式->觀察者模式

觀察者模式能很是大的減小模塊以前的耦合。具體的觀察者模式,客官們能夠去看《設計模式》或者《Head first設計模式》等之類的書。java


在java中,java.util庫中封裝了觀察者模式。在C++中並無這玩意。如下就是爲了封裝一個C++的觀察者模式而寫。git


觀察者模式中,對於主題(subject)和觀察者(observer)的接口能夠是抽象出來的,而這些接口差很少都是通用的,而後要用時只要去繼承這些接口,完成相應的處理便可。java中的實現也是同樣的道理。github


觀察者,很明顯是要去觀察同樣東西。可是,對於不一樣的具體實現,要觀 察的東西並不一樣啊!好比要實現一個天氣預報的,我要觀察溫度、溼度等。要實現一個消息的顯示程序,那麼我要觀察的就是消息了。對於不一樣的實現,有些要觀察 的不僅一個變量,有的只有一個變量。在C++中,可使用變長的參數表,可是,這樣的實現會帶來不少問題,好比類型安全等。還有什麼辦法能夠處理不定個變 量呢?目前,我能想到的就只有用類、結構體去封裝了。那麼要適應不一樣的類呢?那就要用到模板了。設計模式

如下是初步的實現。安全

subject類的設計以下:函數

template <typename TContent>
class Subject
{
public:
    typedef TContent Content;     ///< 觀察的內容類型
    typedef Observer<Content> AbstractObserver;     ///< 觀察者的抽象類型

    void registerObserver(AbstractObserver *obs);

    void unregisterObserver(AbstractObserver *obs);

    void notifyObservers(TContent cnt);
private:
    typedef std::list<AbstractObserver*> ObserverList;
    typedef typename ObserverList::iterator ObserverListIterator;
    ObserverList _observers;

};this

 

這裏將要觀察的內容設爲TContent,若是要觀察多個值的對象,能夠封裝一個struct,而後作爲模板參數傳進來。設計


observer類的設計以下:server

 

template <typename TContent>
class Observer
{
public:
    typedef TContent Content;

    /**
     * @brief update 當有新內容時會被調用
     *
     * 子類化此類,重寫這個函數
     * @param cnt 將的內容經過這個參數傳入
     */
    virtual void update(TContent cnt) = 0;

private:
};對象

 

具體的實現代碼,能夠參見個人github。


這樣封裝後,就能夠很方便使用了。如下是我使用的一個例子。

class ConcreteSubject : public Subject<int>
{
public:
    ConcreteSubject() : times(0)
    {

    }

    void run()
    {
        this->notifyObservers(times);
        ++times;
    }

private:
    int times;
};

class ConcreteObserver : public Observer<int>
{
public:
    virtual void update(int cnt)
    {
        cout << cnt << endl;
    }
};

丫丫吧,好店大全,暢銷產品推薦 http://www.yayaba.cn

相關文章
相關標籤/搜索