1. 程式人生 > >【設計模式】中介者模式

【設計模式】中介者模式

col com fin 每一個 mediator std 一對一 類的方法 -1

1、 定義

1.1 標準定義

中介者模式的定義為:Define an object that encapsulates how a set of objectsinteract.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.(用一個中介對象封裝一系列的對象交互, 中介者使各對象不需要顯示地相互作用, 而使其耦合松散,而且可以獨立地改變它們之間的交互。)

1.2 通用類圖

技術分享

● Mediator 抽象中介者角色
抽象中介者角色定義統一的接口,用於各同事角色之間的通信。
● Concrete Mediator 具體中介者角色
具體中介者角色通過協調各同事角色實現協作行為,因此它必須依賴於各個同事角色。
● Colleague 同事角色
每一個同事角色都知道中介者角色,而且與其他的同事角色通信的時候,一定要通過中介者角色協作。每個同事類的行為分為兩種:一種是同事本身的行為,比如改變對象本身的狀態,處理自己的行為等,這種行為叫做自發行為( Self-Method),與其他的同事類或中介者沒有任何的依賴;第二種是必須依賴中介者才能完成的行為,叫做依賴方法(DepMethod)。

2、實現

2.1 類圖

技術分享

Colleage抽象同事類,而ConcreteColleage是具體同事類,每個具體同事只知道自己的行為,而不了解其他同事類的情況,但它們卻都認識中介者對象,Mediator是抽象中介者,定義了同事對象到中介者對象的接口,ConcreteMediator是具體中介者對象,實現抽象類的方法,它需要知道所有具體同事類,並從具體同事接受消息,向具體同事對象發出命令。

Colleage類,抽象同事類

Mediator類,抽象中介者類

說明:
1. Mediator 模式中,每個Colleague 維護一個 Mediator,當要進行通信時,每個具體的 Colleague 直接向ConcreteMediator 發信息,至於信息發到哪裏,則由 ConcreteMediator 來決定。
2. ConcreteColleagueA 和 ConcreteColleagueB 不必維護對各自的引用,甚至它們也不知道各個的存在。

2.2 代碼

2.2.1 mediator類

// Mediator.h

#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_

#include <string>

using namespace std;

class Mediator;

class Colleage
{
public:
    virtual ~Colleage();
    virtual void SetMediator(Mediator*);
    virtual void SendMsg(string) = 0;
    virtual void GetMsg(string) = 0;
protected:
    Colleage(Mediator*);
    Mediator* _mediator;
private:
};

class ConcreteColleageA : public Colleage
{
public:
    ~ConcreteColleageA();
    ConcreteColleageA(Mediator*);
    virtual void SendMsg(string msg);
    virtual void GetMsg(string);
protected:
private:
};

class ConcreteColleageB : public Colleage
{
public:
    ~ConcreteColleageB();
    ConcreteColleageB(Mediator*);
    virtual void SendMsg(string msg);
    virtual void GetMsg(string);
protected:
private:
};

class Mediator
{
public:
    virtual ~Mediator();
    virtual void SendMsg(string,Colleage*) = 0;
protected:
    Mediator();
private:
};

class ConcreteMediator : public Mediator
{
public:
    ConcreteMediator();
    ~ConcreteMediator();
    void SetColleageA(Colleage*);
    void SetColleageB(Colleage*);
    virtual void SendMsg(string msg,Colleage*);
protected:
private:
    Colleage* m_ColleageA;
    Colleage* m_ColleageB;
};
#endif
// Mediator.cpp

#include "Mediator.h"
#include <iostream>
#include <string>

using namespace std;

Colleage::Colleage(Mediator* pMediator)
{
    this->_mediator = pMediator;
}

Colleage::~Colleage(){}

void Colleage::SetMediator(Mediator* pMediator)
{
    this->_mediator = pMediator;
}

ConcreteColleageA::ConcreteColleageA(Mediator* pMediator) : Colleage(pMediator){}

ConcreteColleageA::~ConcreteColleageA(){}

void ConcreteColleageA::SendMsg(string msg)
{
    this->_mediator->SendMsg(msg,this);
}

void ConcreteColleageA::GetMsg(string msg)
{
    cout << "ConcreteColleageA Receive:"<< msg << endl;
}

ConcreteColleageB::ConcreteColleageB(Mediator* pMediator) : Colleage(pMediator){}

ConcreteColleageB::~ConcreteColleageB(){}

void ConcreteColleageB::SendMsg(string msg)
{
    this->_mediator->SendMsg(msg,this);
}

void ConcreteColleageB::GetMsg(string msg)
{
    cout << "ConcreteColleageB Receive:" << msg << endl;
}

Mediator::Mediator(){}

Mediator::~Mediator(){}

ConcreteMediator::ConcreteMediator(){}

ConcreteMediator::~ConcreteMediator(){}

void ConcreteMediator::SetColleageA(Colleage* p)
{
    this->m_ColleageA = p;
}

void ConcreteMediator::SetColleageB(Colleage* p)
{
    this->m_ColleageB = p;
}

void ConcreteMediator::SendMsg(string msg,Colleage* p)
{
    if(p == this->m_ColleageA)
    {
        this->m_ColleageB->GetMsg(msg);
    }
    else if(p == this->m_ColleageB)
    {
        this->m_ColleageA->GetMsg(msg);
    }
}

2.2.3 調用

// mian.cpp

#include "Mediator.h"

int main()
{
    ConcreteMediator* pMediator = new ConcreteMediator();

    Colleage* p1 = new ConcreteColleageA(pMediator);
    Colleage* p2 = new ConcreteColleageB(pMediator);

    pMediator->SetColleageA(p1);
    pMediator->SetColleageB(p2);

    p1->SendMsg("xxx");
    p2->SendMsg("ooo");
    return 0;
}

3、優缺點

3.1 優點

中介者模式的優點就是減少類間的依賴,把原有的一對多的依賴變成了一對一的依賴,同事類只依賴中介者,減少了依賴,當然同時也降低了類間的耦合。

3.2 缺點

中介者模式的缺點就是中介者會膨脹得很大,而且邏輯復雜,原本N個對象直接的相互依賴關系轉換為中介者和同事類的依賴關系,同事類越多,中介者的邏輯就越復雜。

4、應用

● N個對象之間產生了相互的依賴關系( N2) 。
多個對象有依賴關系, 但是依賴的行為尚不確定或者有發生改變的可能, 在這種情況下一般建議采用中介者模式, 降低變更引起的風險擴散。
產品開發。一個明顯的例子就是MVC框架,把中介者模式應用到產品中,可以提升產品的性能和擴展性,但是對於項目開發就未必, 因為項目是以交付投產為目標,而產品則是以穩定、高效、擴展為宗旨。

【設計模式】中介者模式