C++設計模式之中介者模式(mediator)(行爲型)

一 定義

中介者模式:用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。

二 ULM圖

角色

抽象中介者(Mediator):中介者定義一個接口用於與各同事(Colleague)對象通信。
具體中介者(ConcreteMediator): 具體中介者通過協調各同事對象實現協作行爲。瞭解並維護它的各個同事。
抽象同事類(Colleague class): 定義同事類接口,定義各同事的公有方法.
具體同事類(ConcreteColleague): 實現抽象同事類中的方法。每一個同時類需要知道中介者對象;每個具體同事類只需要瞭解自己的行爲,而不需要了解其他同事類的情況。每一個同事對象在需與其他的同事通信的時候,與它的中介者通信。

中介者模式的優點
1) 減少了子類生成:  Mediator將原本分佈於多個對象間的行爲集中在一起。改變這些行爲只需生成Mediator的子類即可。這樣各個Colleague類可被重用。
2) 簡化各同事類的設計和實現 : 它將各同事類Colleague解耦,Mediator有利於各Colleague間的松耦合. 你可以獨立的改變和複用各Colleague類和Mediator類。
3) 它簡化了對象協議: 用Mediator和各Colleague間的一對多的交互來代替多對多的交互。一對多的關係更易於理解、維護和擴展。
4) 它對對象如何協作進行了抽象 將中介作爲一個獨立的概念並將其封裝在一個對象中,使你將注意力從對象各自本身的行爲轉移到它們之間的交互上來。這有助於弄清    楚一個系統中的對象是如何交互的。
5) 它使控制集中化 中介者模式將交互的複雜性變爲中介者的複雜性。
中介者模式的缺點
因爲中介者封裝了協議,即在具體中介者類中包含了同事之間的交互細節,可能會導致具體中介者類非常複雜,這可能使得中介者自身成爲一個難於維護的龐然大物。

三 實例

以租房爲例子,如果沒有房屋中介,那麼房客要自己找房東,而房東也要自己找房客,非常不方便。有了房屋中介機構就方便了,房東可以把要出租的房屋信息放到中介機構,而房客可以去中介機構諮詢。在軟件中,就是多個對象之間需要通信,如果沒有中介,對象就需要知道其他對象,最壞情況下,可能需要知道所有其他對象,而有了中介對象就方便多了,對象只需與中介對象通信,而不用知道其他的對象,這就是中介者模式。

#include <iostream>
#include <string>

class Mediator;
//抽象人
class Person
{
protected:
    Mediator *mediator; //中介
public:
    virtual void setMediator(Mediator *){} //設置中介
    virtual void sendMessage(const std::string&) {}    //向中介發送信息
    virtual void getMessage(const std::string&) {}     //從中介獲取信息
};

//抽象中介機構
class Mediator
{
public:
    virtual void send(const std::string& , Person *) {}
    virtual void setRenter(Person *) {}  //設置其中一方
    virtual void setLandlord(Person *) {}
};

//租房者
class Renter: public Person
{
public:
    void setMediator(Mediator *mediator)
    {
        this->mediator = mediator;
    }
    void sendMessage(const std::string& message)
    {
        mediator->send(message, this);
    }
    void getMessage(const std::string& message)
    {
        std::cout << "租房者收到信息" << message;
    }
};

//房東
class Landlord: public Person
{
public:
    void setMediator(Mediator *mediator)
    {
        mediator = mediator;
    }
    void sendMessage(const std::string& message)
    {
         mediator->send(message, this);
    }
    void getMessage(const std::string& message)
    {
        std::cout << "房東收到信息:" << message;
    }
};
//房屋中介
class HouseMediator : public Mediator
{
private:
    Person *renter; //租房者
    Person *landlord; //房東
public:
    HouseMediator()
    : renter{nullptr}
    , landlord{nullptr}
    {}
    void setRenter(Person *renter)
    {
        this->renter = renter;
    }
    void setLandlord(Person *landlord)
    {
        this->landlord = landlord;
    }
    void send(const std::string& message, Person *person)
    {
        if(person == renter) //租房者給房東發信息
            landlord->getMessage(message); //房東收到信息
        else
            renter->getMessage(message);
    }
};

//客戶端代碼
int main()
{
    Mediator *mediator = new HouseMediator();
    Person *person1 = new Renter();    //租房者
    Person *person2 = new Landlord();  //房東

    mediator->setRenter(person1);
    mediator->setLandlord(person2);
    person1->setMediator(mediator);
    person2->setMediator(mediator);
    person1->sendMessage("我想在南京路附近租套房子,價格800元一個月\n");
    person2->sendMessage("出租房子:南京路100號,70平米,1000元一個月\n");

    delete person1; delete person2; delete mediator;

    return 0;
}

 

與其他相關模式

1)外觀模式,Facade與中介者的不同之處在於它是對一個對象子系統進行抽象,從而提供了一個爲方便的接口。它的協議是單向的,即 Facade對象對這個子系統類提出請求,但反之則不。相反,Mediator提供了各Colleague對象不支持或不能支持的協作行爲,而且協議是多向。
2) Colleague可使用Observers模式與Mediator通信。

總結與分析

1)迪米特法則的一個典型應用:在中介者模式中,通過創造出一箇中介者對象,將系統中有關的對象所引用的其他對象數目減少到最少,使得一個對象與其同事之間的相互作用被這個對象與中介者對象之間的相互作用所取代。因此,中介者模式就是迪米特法則的一個典型應用。
2) 通過引入中介者對象,可以將系統的網狀結構變成以中介者爲中心的星形結構,中介者承擔了中轉作用和協調作用。中介者類是中介者模式的核心,它對整個系統進行控制和協調,簡化了對象之間的交互,還可以對對象間的交互進行進一步的控制。
3) 中介者模式的主要優點在於簡化了對象之間的交互,將各同事解耦,還可以減少子類生成,對於複雜的對象之間的交互,通過引入中介者,可以簡化各同事類的設計和實現;中介者模式主要缺點在於具體中介者類中包含了同事之間的交互細節,可能會導致具體中介者類非常複雜,使得系統難以維護。
4) 中介者模式適用情況包括:系統中對象之間存在複雜的引用關係,產生的相互依賴關係結構混亂且難以理解;一個對象由於引用了其他很多對象並且直接和這些對象通信,導致難以複用該對象;想通過一箇中間類來封裝多個類中的行爲,而又不想生成太多的子類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章