iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
自我挑戰組

設計模式系列 第 23

Day23 - 觀察者模式(Observer pattern)

  • 分享至 

  • xImage
  •  

介紹
觀察者模式定義物件間一種一對多的依賴關係,使得每當一物件的狀態改變,所有依賴它的物件都會被通知。

C++範例

#include <iostream>
#include <list>

class Observer;

// 抽象被觀察者
class Subject
{
public:
    Subject() : m_State(0)
    {
    }
    virtual ~Subject() = default;

    virtual void Attach(const std::shared_ptr<Observer> pObserver) = 0;
    virtual void Detach(const std::shared_ptr<Observer> pObserver) = 0;
    virtual void Notify() = 0;

    virtual int GetState()
    {
        return m_State;
    }
    void SetSate(int state)
    {
        std::cout << "Subject updated!" << std::endl;
        m_State = state;
    }

protected:
    std::list<std::shared_ptr<Observer>> m_ObserverList;
    int m_State;
};

// 抽象觀察者
class Observer
{
public:
    virtual ~Observer() = default;

    Observer(const std::shared_ptr<Subject> pSubject, const std::string& name = "unknown") :
        m_pSubject(pSubject),
        m_Name(name)
    {
    }

    virtual void Update() = 0;

    virtual const std::string& Name()
    {
        return m_Name;
    }

protected:
    std::shared_ptr<Subject> m_pSubject;
    std::string m_Name;
};

// 具體被觀察者
class ConcreteSubject : public Subject
{
public:
    void Attach(const std::shared_ptr<Observer> pObserver) override
    {
        auto iter = std::find(m_ObserverList.begin(), m_ObserverList.end(), pObserver);
        if (iter == m_ObserverList.end())
        {
            std::cout << "Attach observer " << pObserver->Name() << std::endl;
            m_ObserverList.emplace_back(pObserver);
        }
    }

    void Detach(const std::shared_ptr<Observer> pObserver) override
    {
        std::cout << "Detach observer" << pObserver->Name() << std::endl;
        m_ObserverList.remove(pObserver);
    }

    void Notify() override
    {
        for (auto it = m_ObserverList.begin(); it != m_ObserverList.end(); it++)
        {
            (*it)->Update();
        }
    }
};

class Observer1 : public Observer
{
public:
    Observer1(const std::shared_ptr<Subject> pSubject, const std::string& name = "unknown") :
        Observer(pSubject, name)
    {
    }

    void Update() override
    {
        std::cout << "Observer1_" << m_Name << " state is: " << m_pSubject->GetState() << std::endl;
    }
};

class Observer2 : public Observer
{
public:
    Observer2(const std::shared_ptr<Subject> pSubject, const std::string& name = "unknown") :
        Observer(pSubject, name)
    {
    }

    void Update() override
    {
        std::cout << "Observer2_" << m_Name << " state is: " << m_pSubject->GetState() << std::endl;
    }
};

int main()
{
    std::shared_ptr<Subject> pSubject = std::make_shared<ConcreteSubject>();

    std::shared_ptr<Observer> observer1_1 = std::make_shared<Observer1>(pSubject, "1");
    std::shared_ptr<Observer> observer1_2 = std::make_shared<Observer1>(pSubject, "2");
    std::shared_ptr<Observer> observer1_3 = std::make_shared<Observer1>(pSubject, "3");

    std::shared_ptr<Observer> observer2_4 = std::make_shared<Observer2>(pSubject, "4");
    std::shared_ptr<Observer> observer2_5 = std::make_shared<Observer2>(pSubject, "5");
    std::shared_ptr<Observer> observer2_6 = std::make_shared<Observer2>(pSubject, "6");


    pSubject->Attach(observer1_1);
    pSubject->Attach(observer1_2);
    pSubject->Attach(observer1_3);
    pSubject->Attach(observer2_4);
    pSubject->Attach(observer2_5);
    pSubject->Attach(observer2_6);

    pSubject->SetSate(2);
    pSubject->Notify();

    pSubject->Detach(observer1_1);
    pSubject->Detach(observer1_2);

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

    return 0;
}

Output:

Attach observer 1
Attach observer 2
Attach observer 3
Attach observer 4
Attach observer 5
Attach observer 6
Subject updated!
Observer1_1 state is: 2
Observer1_2 state is: 2
Observer1_3 state is: 2
Observer2_4 state is: 2
Observer2_5 state is: 2
Observer2_6 state is: 2
Detach observer1
Detach observer2
Subject updated!
Observer1_3 state is: 3
Observer2_4 state is: 3
Observer2_5 state is: 3
Observer2_6 state is: 3

Ref:
https://blog.csdn.net/leonardohaig/article/details/120187956


上一篇
Day22 - 中介者模式(Mediator pattern)
下一篇
Day24 - 模板模式(Template pattern)
系列文
設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言