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;
}
posted @ 2022-02-17 18:33  冰糖葫芦很乖  阅读(794)  评论(0编辑  收藏  举报