C++設計模式——觀察者模式


觀察者模式的使用場景

1.當一個抽象模型有兩個方面,其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立的改變和復用;

2.當對一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變;

3.觀察者模式所做的工作其實就是在接觸耦合。讓耦合的雙方都依賴於抽象,而不依賴於具體,從而使得各自的變化都不會影響到另外一邊的變化

#include <iostream>
#include <list>
using namespace std;

//Observer類 抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己。這個接口要做更新接口。
//觀察者一般用一個抽象類或者接口實現,更新接口通常包含一個Update()方法 這個方法叫做更新方法。
class Observer
{
public:
    virtual void Update(int) = 0;
};

//Subject類 可翻譯為主題或抽象通知者 一般用一個抽象類或者一個接口實現。他把所有對觀察者對象的引用保存 //在一個聚集里,每個主題都可以又任何數量的觀察者。抽象主題提供一個接口,可增加或者刪除觀察者對象
class Subject
{
public:
    virtual void Attach(Observer*) = 0;
    virtual void Detach(Observer*) = 0;
    virtual void Notify() = 0;
};

//ConcreteObserver 具體觀察者 實現抽象觀察角色所要求的更新接口,以便使本身的狀態與主題的狀態相協調.
//具體觀察者角色可以保存一個指向具體主題對象的引用.具體觀察者校色通常用一個具體子類實現
class ConcreteObserver : public Observer
{
public:
    ConcreteObserver(Subject* pSubject) : m_pSubject(pSubject) {}
    void Update(int value)
    {
        cout << "ConcreteObserver 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;
};

//ConcreteSubject類,叫做具體主題或者具體通知者..將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時...給所有登記過的觀察者發出通知. //具體主題對象通常用一個具體子類實現.
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;
};


int main()
{
    // Create Subject
    ConcreteSubject* pSubject = new ConcreteSubject();

    // Create Observer
    Observer* pObserver = new ConcreteObserver(pSubject);
    Observer* pObserver2 = new ConcreteObserver2(pSubject);

    // Change the state
    pSubject->SetState(2);

    // Register the observer
    pSubject->Attach(pObserver);
    pSubject->Attach(pObserver2);

    pSubject->Notify();

    // Unregister the observer
    pSubject->Detach(pObserver);

    pSubject->SetState(3);
    pSubject->Notify();

    delete pObserver;
    delete pObserver2;
    delete pSubject;
    system("pause");
    return 0;
}

 

參考——https://www.cnblogs.com/carsonzhu/p/5770253.html

參考——大話設計模式

上面這個有不足之處是  萬一沒有抽象觀察者這樣的接口,通知功能就完不成了.... 而且每個通知的內容是不一樣的

#include <iostream>
#include <string>
#include <list>
using namespace std;

class Subject;
//抽象觀察者
class Observer
{
protected:
    string name;
    Subject* sub;
public:
    Observer(string name, Subject* sub)
    {
        this->name = name;
        this->sub = sub;
    }
    virtual void update() = 0;
};
//具體的觀察者,看股票的
class StockObserver :public Observer
{
public:
    StockObserver(string name, Subject* sub) :Observer(name, sub)
    {
    }
    void update();
};
//具體的觀察者,看NBA的
class NBAObserver :public Observer
{
public:
    NBAObserver(string name, Subject* sub) :Observer(name, sub)
    {
    }
    void update();
};
//抽象通知者
class Subject
{
protected:
    list<Observer*> observers;
public:
    string action;
    virtual void attach(Observer*) = 0;
    virtual void detach(Observer*) = 0;
    virtual void notify() = 0;
};
//具體通知者,秘書
class Secretary :public Subject
{
    void attach(Observer* observer)
    {
        observers.push_back(observer);
    }
    void detach(Observer* observer)
    {
        list<Observer*>::iterator iter = observers.begin();
        while (iter != observers.end())
        {
            if ((*iter) == observer)
            {
                observers.erase(iter);
            }
            ++iter;
        }
    }
    void notify()
    {
        list<Observer*>::iterator iter = observers.begin();
        while (iter != observers.end())
        {
            (*iter)->update();
            ++iter;
        }
    }
};

void StockObserver::update()
{
    cout << name << " 收到消息:" << sub->action << endl;
    if (sub->action == "梁所長來了!")
    {
        cout << "我馬上關閉股票,裝做很認真工作的樣子!" << endl;
    }
}

void NBAObserver::update()
{
    cout << name << " 收到消息:" << sub->action << endl;
    if (sub->action == "梁所長來了!")
    {
        cout << "我馬上關閉NBA,裝做很認真工作的樣子!" << endl;
    }
}

int main()
{
    Subject* dwq = new Secretary(); //創建觀察者<br>    //被觀察的對象
    Observer* xs = new NBAObserver("xiaoshuai", dwq);
    Observer* zy = new NBAObserver("zouyue", dwq);
    Observer* lm = new StockObserver("limin", dwq);
    //加入觀察隊列
    dwq->attach(xs);
    dwq->attach(zy);
    dwq->attach(lm);
    //事件
    dwq->action = "去吃飯了!";//通知
    dwq->notify();
    cout << endl;
    dwq->action = "梁所長來了!";
    dwq->notify();
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM