iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
自我挑戰組

設計模式系列 第 22

Day22 - 中介者模式(Mediator pattern)

  • 分享至 

  • xImage
  •  

介紹
中介者模式封裝一系列的物件互動,物件間的互動皆透過中介來完成,此降低物件間的依賴關係。

C++範例

#include <iostream>
#include <memory>
#include <vector>

enum PersonType
{
    RENTER = 0,
    LANDLORD
};

class Mediator;

// 抽象人員類
class Person
{
public:
    Person(const std::shared_ptr<Mediator> pMediator, PersonType type) :
        m_mediator(pMediator),
        personType(type)
    {
    }
    virtual ~Person() = default;

    virtual void SendMessage(const std::string &msg) = 0;
    virtual void GetMessage(const std::string &msg) = 0;

    PersonType personType;

protected:
    std::shared_ptr<Mediator> m_mediator;
};

// 抽象仲介
class Mediator
{
public:
    virtual ~Mediator() = default;

    virtual void Send(const std::string &msg, PersonType type) const = 0;
    virtual void Register(std::shared_ptr<Person> spPerson) = 0;
};

// 租房客A
class RenterA : public Person
{
public:
    RenterA(const std::shared_ptr<Mediator> mediator) :
        Person(mediator, PersonType::RENTER)
    {
    }

    void SendMessage(const std::string &msg) override
    {
        m_mediator->Send(msg, PersonType::RENTER);
    }
    void GetMessage(const std::string &msg) override
    {
        std::cout << "RenterA received message: " << msg << std::endl;
    }
};

// 租房客B
class RenterB : public Person
{
public:
    RenterB(const std::shared_ptr<Mediator> mediator) :
        Person(mediator, PersonType::RENTER)
    {
    }

    void SendMessage(const std::string &msg) override
    {
        m_mediator->Send(msg, PersonType::RENTER);
    }
    void GetMessage(const std::string &msg) override
    {
        std::cout << "RenterB received message: " << msg << std::endl;
    }
};

// 房東
class Landlord : public Person
{
public:
    Landlord(const std::shared_ptr<Mediator> mediator) :
        Person(mediator, PersonType::LANDLORD)
    {
    }

    void SendMessage(const std::string &msg) override
    {
        m_mediator->Send(msg, PersonType::LANDLORD);
    }
    void GetMessage(const std::string &msg) override
    {
        std::cout << "Landlord received message: " << msg << std::endl;
    }
};

class HouseMediator : public Mediator
{
public:
    void Register(const std::shared_ptr<Person> spPerson) override
    {
        auto iter = m_PersonList.begin();
        for (; iter != m_PersonList.end(); iter++)
        {
            if (*iter == spPerson)
                break;
        }
        if (iter == m_PersonList.end())
        {
            m_PersonList.emplace_back(spPerson);
        }
    }

    void Send(const std::string &msg, PersonType type) const override
    {
        for (const auto item : m_PersonList)
        {
            if (type == PersonType::RENTER)
            {
                // 租屋客的訊息只讓房東接收
                if (item->personType == PersonType::LANDLORD)
                    item->GetMessage(msg);
            }
            else if (type == PersonType::LANDLORD)
            {
                // 租東的訊息只讓租屋客接收
                if (item->personType == PersonType::RENTER)
                    item->GetMessage(msg);
            }
        }
    }

private:
    std::vector<std::shared_ptr<Person>> m_PersonList;
};

int main()
{
    std::shared_ptr<Mediator> pHouseMediator = std::make_shared<HouseMediator>();
    std::shared_ptr<Person> pRenterA = std::make_shared<RenterA>(pHouseMediator);
    std::shared_ptr<Person> pRenterB = std::make_shared<RenterB>(pHouseMediator);
    std::shared_ptr<Person> pLandlord = std::make_shared<Landlord>(pHouseMediator);

    pHouseMediator->Register(pRenterA);
    pHouseMediator->Register(pRenterB);
    pHouseMediator->Register(pLandlord);
    
    pLandlord->SendMessage("House for renting");
    
    pRenterA->SendMessage("I want it");

    return 0;
}

Output:

RenterA received message: House for renting
RenterB received message: House for renting
Landlord received message: I want it

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


上一篇
Day21 - 備忘錄模式(Memento pattern)
下一篇
Day23 - 觀察者模式(Observer pattern)
系列文
設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言