【設計模式】——中介者模式

中介者模式(Mediator),用一箇中介者對象來封裝一系列的對象交互。中介者使各對象不須要顯示地相互引用,從而使其耦合鬆散,並且能夠獨立地改變他們之間的交互。ios

  Colleague叫作抽象同事類,而ConcreteColleague是具體同事類,每一個具體同事只知道本身的行爲,而不瞭解其餘同事類的狀況,但它們卻都認識中介者對象,Mediator是抽象中介者,定義了同事對象到中介者對象的接口,ConcreteMediator是具體中介者對象,實現抽象類的方法,它須要知道全部具體同事類,並從具體同事接收消息,向具體同事對象發出命令。安全

#include <iostream>

using namespace std;
class Colleague;
//Mediator類,抽象中介者
class Mediator
{
public:
    //定義一個抽象的發送消息的方法,獲得同事對象和發送消息
    virtual void Send(string message,Colleague *colleague)=0;
};
//Colleague類 抽象同事類
class Colleague
{
protected:
    Mediator *m_mediator;
public:
    Colleague(Mediator *mediator)
    {
        this->m_mediator=mediator;
    }
};
//ConcreteColleague1和ConcreteColleague2等各類同事對象
class ConcreteColleague1:public Colleague
{
public:
    ConcreteColleague1(Mediator *mediator):Colleague(mediator){}
    void Send(string message)
    {
        m_mediator->Send(message,this);
    }
    void Notify(string message)
    {
        cout << "同事1獲得消息:" << message << endl;
    }
};
class ConcreteColleague2:public Colleague
{
public:
    ConcreteColleague2(Mediator *mediator):Colleague(mediator){}
    void Send(string message)
    {
        m_mediator->Send(message,this);
    }
    void Notify(string message)
    {
        cout << "同事2獲得消息:" << message << endl;
    }
};
//ConcreteMediator 具體中介者
class ConcreteMediator:public Mediator
{
private:
    ConcreteColleague1 *m_colleague1;
    ConcreteColleague2 *m_colleague2;
public:
    void setColleague1(ConcreteColleague1 *colleague1)
    {
        this->m_colleague1=colleague1;
    }
    ConcreteColleague1 *getColleague1()
    {
        return m_colleague1;
    }
    void setColleague2(ConcreteColleague2 *colleague2)
    {
        this->m_colleague2=colleague2;
    }
    ConcreteColleague2 *getColleague2()
    {
        return m_colleague2;
    }
    void Send(string message,Colleague *colleague)
    {
        if(colleague==m_colleague1)
            m_colleague2->Notify(message);
        else
            m_colleague1->Notify(message);
    }
};
int main()
{
    ConcreteMediator *m=new ConcreteMediator();
    //讓兩個具體同時類認識中介對象
    ConcreteColleague1 *c1=new ConcreteColleague1(m);
    ConcreteColleague2 *c2=new ConcreteColleague2(m);
    //讓中介者認識各個具體同事類對象
    m->setColleague1(c1);
    m->setColleague2(c2);
    //具體同事類對象的發送消息都經過中介者轉發
    c1->Send("吃過飯了嗎?");
    c2->Send("沒有呢,你打算請客?");
    return 0;
}

因爲有了Mediator,使得ConcreteColleague1和ConcreteColleague2在發送消息和接收消息時實際上是經過中介者來完成的,這就減小了他們之間的耦合度。this

下面看一個例子:spa

#include <iostream>

using namespace std;
class Country;
//聯合國機構類,至關於Mediator類
class UnitedNations
{
public:
    virtual void Declare(string message,Country *colleague)=0;
};
//國家類,至關於Colleague類
class Country
{
protected:
    UnitedNations *m_mediator;
public:
    Country(UnitedNations *mediator)
    {
        this->m_mediator=mediator;
    }
};
//美國類,至關於ConcreteColleague1類
class USA:public Country
{
public:
    USA(UnitedNations *mediator):Country(mediator){}
    void Declare(string message)
    {
        m_mediator->Declare(message,this);
    }
    void GetMessage(string message)
    {
        cout << "美國得到對象消息:" << message << endl;
    }
};
//伊拉克類
class Iraq:public Country
{
public:
    Iraq(UnitedNations *mediator):Country(mediator){}
    void Declare(string message)
    {
        m_mediator->Declare(message,this);
    }
    void GetMessage(string message)
    {
        cout << "伊拉克得到對象消息:" << message << endl;
    }
};
//聯合國安全理事會
class UnitedNationsSecurityCouncil:public UnitedNations
{
private:
    USA *m_colleague1;
    Iraq *m_colleague2;
public:
    void SetUSA(USA *colleague1)
    {
        this->m_colleague1=colleague1;
    }
    USA *GetUSA()
    {
        return m_colleague1;
    }
    void SetIraq(Iraq *colleague2)
    {
        this->m_colleague2=colleague2;
    }
    Iraq *GetIraq()
    {
        return m_colleague2;
    }
    void Declare(string message,Country *colleague)
    {
        if(colleague==m_colleague1)
            m_colleague2->GetMessage(message);
        else
            m_colleague1->GetMessage(message);
    }
};
int main()
{
    UnitedNationsSecurityCouncil *UNSC=new UnitedNationsSecurityCouncil();
    USA *c1=new USA(UNSC);
    Iraq *c2=new Iraq(UNSC);
    UNSC->SetUSA(c1);
    UNSC->SetIraq(c2);
    c1->Declare("不許研製核武器,不然要發動戰爭!");
    c2->Declare("咱們沒有核武器,也不怕侵略!");
    return 0;
}

  中介者模式很容易在系統中應用,也很容易在系統中誤用。當系統出現了「多對多」交互複雜的對象羣時,不要急於使用中介模式,而要先反思你的系統在設計上是否是合理。設計

  優勢:Mediator的出現減小了各個Colleague的耦合,使得能夠獨立地改變和複用各個Colleague類和Mediator;因爲把對象如何協做進行了抽象,將中介做爲一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各自自己的行爲轉移到他們之間的交互上來,也就是站在一個更宏觀的角度看待系統。3d

  缺點:因爲ConcreteMediator控制了集中化,因而就把交互複雜性變爲了中介者的複雜性,這就使得中介者會變得比任何一個ConcreteColleague都複雜。code

中介者模式通常用於一組對象以定義良好可是複雜的方式進行通訊的場合,以及想定製一個分佈在多個類中的行爲,而又不想生成太多的子類的場合。對象

相關文章
相關標籤/搜索