中介者模式-对象行为模式

意图:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。

动机

面向对象设计鼓励将行为分布到各个对象中。这种分布可能会导致对象间有许多连接。最坏的情况,每个对象都知道其他所有对象。

虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其复用性。

通过将集体行为封装在一个单独的中介者对象中。中介者负责控制和协调一组对象间的交互。中介者充当一个中介以使组中的对象不再显示相互引用。这些对象仅知道中介者,从而减少了相互连接的数目。

适用性:

以下情况使用中介者模式:

1一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。

2一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。

3想定制一个分布在多个类中的行为,而又不想生成太多的子类。

结构:


参与者:

Mediator:中介者定义一个接口用于与各同事对象通信。

ConcreteMediator:具体中介者通过协调同事对象实现协作行为。了解并维护它的各个同事。

Colleagueclass(同事类):

每一个同事类都知道它的中介者对象。

每一个同事对象在需与其他的同事对象通信的时候,与它的中介者通信。

如下图:

 

协作:

同事向一个中介者对象发送和接收请求。中介者在各个同事间适当的转发请求以实现协作行为

效果(有以下优缺点)

1减少了子类生成,mediator将对象间的行为集中在一起,改变这些行为只需生成mediator子类即可,各个colleague类可被重用

2将各Colleague解耦:实现了松耦合,可以独立的改变和复合各ColleagueMediator

3简化了对象协议:一对多的交互来代替多对多的交互

4对对象如何协作进行了抽象。

5使控制集中化:可能使得中介者成为一个难以维护的庞然大物。(缺点)

实现:

1忽略抽象的Mediator类:当各colleague仅与一个mediator一起工作时,则只需要一个mediator 

2Colleague-Mediator通信,两种实现方式:

(1)使用observer模式,mediator实现为observer,各colleague作为subject,一但状态改变则发通知给mediator,mediator做出的相应就是将状态改变的结果传播给其他colleague

(2)在mediator中定义一个特殊的通知接口,各colleague在通讯时直接调用该接口。

相关模式:

Facade与中介者的不同之处在于它是对一个对象子系统进行抽象,从而提供了一个更为方便的接口。它的协议是单向的,即Facade对象对这个子系统类提出请求,但反之则不行。而Mediator提供了各Colleague对象不支持或不能支持的协作行为,而且协议是多向的。

Colleague可使用Observer模式与Mediator通信。


代码:

//中介者模式
 
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;

class Country;
//联合国机构类,相当于Mediator类 
class UnitedNations
{
public:
    virtual void Declare(string message, Country& colleage) = 0;
}; 

//国家类,相当于Colleage类
class Country
{
public:
    Country(UnitedNations& mediator) : 
        _mediator(&mediator) { }
    virtual ~Country()
    {
        
    }
protected:
    UnitedNations* _mediator;
};

//美国类,相当于ConcreteColleague类
class USA : public Country
{
public:
    USA(UnitedNations& mediator) : Country(mediator)
    {}
    
    //声明 
    void Declare(string message)
    {
        _mediator->Declare(message, *this);
    } 
    
    void GetMessage(string message)
    {
        cout << "美国获得对方信息:" << message << endl;
    }
}; 
 
 //伊拉克类,相当于ConcreteColleague类
class Iraq : public Country
{
public:
    Iraq(UnitedNations& mediator) : Country(mediator)
    {}
    
    //声明 
    void Declare(string message)
    {
        _mediator->Declare(message, *this);
    } 
    
    void GetMessage(string message)
    {
        cout << "伊拉克获得对方信息:" << message << endl;
    }
}; 

//联合国安理事会,具体的中介者类 
class UnitedNationsSecurityCouncil : public UnitedNations
{
public: 
    UnitedNationsSecurityCouncil()
    {
        colleague1 = new USA(*this);
        colleague2 = new Iraq(*this);
    }
    
    void Declare(string message, Country& colleague)
    {
        //如果是美国,则发送给伊拉克,否则发送给美国 
        if (typeid(colleague) == typeid(USA))
            colleague2->GetMessage(message);
        else
            colleague1->GetMessage(message); 
    } 
    
    ~UnitedNationsSecurityCouncil()
    {
        delete colleague1;
        delete colleague2;
    } 
private:
    USA* colleague1;
    Iraq* colleague2; 
}; 

int main()
{
    UnitedNationsSecurityCouncil UNSC;
    
    USA usa(UNSC);
    Iraq Iraq(UNSC);
    
    usa.Declare("不准研制核武器,否则要发动战争!");
    Iraq.Declare("我们没有核武器,也不怕侵略"); 
    
    system("pause");
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值