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

中介者模式适合于 系统中不希望对象之间直接交互,即不希望类之间相互包含,成为朋友。

中介者模式中有四种角色:

(1)中介者:定义了用于同事之间通信的方法

(2)具体中介者:如果只有一个中介者,那么可以只有一个具体中介者,不需要抽象中介者。它包含具体同事的引用,实现他们之间的通信。

(3)同事:抽象类,规定一些方法

(4)具体同事:包含具体中介者的引用,一个具体同事需要和其他同事交互时,将自己的请求通知给他包含的具体中介者即可。

在本例子中,同事A分别需要通知B和C一些消息,而B也需要通知A和C一些消息,同样,C也需要通知A和B一些消息。利用中介者模式实现如下:

(1)Colleague.h

 #ifndef _COLLEAGUE_H_
#define _COLLEAGUE_H_
#include <string>
#include <iostream>
#include "Mediator.h"
using namespace std;
class ConcreteMediator; //中介者模式
//抽象同事和具体同事的定义 如果没有中介者 他们需要相互包含
class Colleague{
public:
virtual void giveMess(string mess[]) = ;
virtual void receiverMess(string mess) = ;
virtual void setName(string name) = ;
virtual string getName() = ; }; //具体同事
class ColleagueA : public Colleague{
public:
ColleagueA(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueB : public Colleague{
public:
ColleagueB(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueC : public Colleague{
public:
ColleagueC(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; #endif

(2)Colleague.cpp

 #include "Colleague.h"

 ColleagueA::ColleagueA(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueA(this);
} void ColleagueA::setName(string name)
{
this->name = name;
} string ColleagueA::getName()
{
return name;
} void ColleagueA::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueA::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueB::ColleagueB(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueB(this);
} void ColleagueB::setName(string name)
{
this->name = name;
} string ColleagueB::getName()
{
return name;
} void ColleagueB::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueB::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueC::ColleagueC(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueC(this);
} void ColleagueC::setName(string name)
{
this->name = name;
} string ColleagueC::getName()
{
return name;
} void ColleagueC::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueC::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
}

(3)Mediator.h

 #ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
#include "Colleague.h"
#include <string>
using namespace std; class Colleague;
class ColleagueA;
class ColleagueB;
class ColleagueC; //中介者 由于本例子中只有一个中介者 所以只定义一个具体中介者 class ConcreteMediator{
public:
void registerColleagueA(ColleagueA *ca);
void registerColleagueB(ColleagueB *cb);
void registerColleagueC(ColleagueC *cc); void deliverMess(Colleague *colleague, string mess[]); private:
ColleagueA *ca;
ColleagueB *cb;
ColleagueC *cc;
}; #endif

(4)Mediator.cpp

 #include "Mediator.h"

 void ConcreteMediator::registerColleagueA(ColleagueA *ca)
{
this->ca = ca;
} void ConcreteMediator::registerColleagueB(ColleagueB *cb)
{
this->cb = cb;
} void ConcreteMediator::registerColleagueC(ColleagueC *cc)
{
this->cc = cc;
} void ConcreteMediator::deliverMess(Colleague *colleague, string mess[])//如果这里需要判断mess的长度,需要将其作为参数传递进来
{
if (typeid(*colleague) == typeid(*ca))
{
//通知其他的同事
cb->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cb))
{
ca->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cc))
{
ca->receiverMess(colleague->getName() + mess[]);
cb->receiverMess(colleague->getName() + mess[]);
}
}

(5)MediatorMain.cpp

 #include "Colleague.h"
#include "Mediator.h" int main()
{
ConcreteMediator *mediator = new ConcreteMediator(); ColleagueA *ca = new ColleagueA(mediator);
ColleagueB *cb = new ColleagueB(mediator);
ColleagueC *cc = new ColleagueC(mediator); ca->setName("国A");
cb->setName("国B");
cc->setName("国C"); string messA[] = { "要求归还100斤土豆", "要求归还20头牛" };
ca->giveMess(messA);
cout << endl;
string messB[] = { "要求归还10只鸡", "要求归还15匹马" };
cb->giveMess(messB);
cout << endl;
string messC[] = { "要求归还300斤小麦", "要求归还50头驴" };
cc->giveMess(messC); return ;
}

需要注意的是,在中介者中传递消息的时候需要判断当前参数中指向的对象是哪种类型,用到了操作符typeid。它的参数类型是对象,若两个对象是同一个类型则返回true。

中介者模式适合于一个对象需要引用很多其他对象,或者是对象之间的相互引用比较多的情况。

优点也有很多,比如:

(1)将分布于多个对象之间的交互行为集中在一起。

(2)使得各个具体同事之间完全解耦。

等。

(七)中介者模式-C++实现的更多相关文章

  1. 23种设计模式--中介者模式-Mediator Pattern

    一.中介者模式的介绍     中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...

  2. 设计模式--中介(Mediator)模式

    时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...

  3. 设计模式---接口隔离模式之中介者模式(Mediator)

    一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...

  4. 行为型模式(五) 中介者模式(Mediator)

    一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...

  5. MediatorPattern(中介者模式)

    /** * 中介者模式 * @author TMAC-J * 研究了这么多设计模式,觉得无非就是几点: * 1.若两个类有耦合关系,设立一个中间类,处理两个类的关系,把两个类的耦合降低 * 2.面向接 ...

  6. C#设计模式-中介者模式

    在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 一. 中介者(Mediator)模式 从 ...

  7. php实现设计模式之 中介者模式

    <?php /* * 中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ /* * 以一个同学qq群为例说明, ...

  8. 轻松掌握:JavaScript代理模式、中介者模式

    代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...

  9. java设计模式之中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...

随机推荐

  1. Horseman - 让你更轻松的使用 PhantomJS

    Horseman 是一个 Node.js 模块,让你可以更轻松的使用 PhantomJS 进行功能测试,页面自动机,网络监控,屏幕捕获等.它提供了直接,链式的 API,易于理解的控制流,避免回调陷阱. ...

  2. Oracle基础和用户管理

    1.数据库的使用: 项目的规模:负载量(用户)有多大? 成本: 安全性:   (小型数据库)access.forbase 负载小 :100人以内,比如留言板,信息管理系统. 成本:千元以内. 安全性要 ...

  3. js实现标准无缝滚动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. SharePoint 2010 站点附加数据升级到SP2013

    首先,去SharePoint 2010的数据库服务器上,找到站点的数据库,备份.还原到SharePoint 2013环境中: 如果不知道数据库服务器是哪台,可以通过服务器场上的服务器查看: 如果不知道 ...

  5. setTimeout和setInterval

    setTimeout(methodName, interval); //间隔时间单位为毫秒,表示interval毫秒后执行方法methodName setInterval(methodName, in ...

  6. Activity与Service进行数据交互

    Android启动Service有两种方法,一种是startService,一种是bindService.生命周期如下: 执行startService时,调用者如果没有stopService,Serv ...

  7. java验证码组件kaptcha使用方法

    使用方法: 项目中导入kaptcha-2.3.jar包在web.xml里面新增: <!-- 登陆验证码Kaptcha -->    <servlet>        <s ...

  8. #VSTS日志# 15/11/18 插件应用市场,RM,包管理器等

    [小编]从今天开始,我将在这个博客上连载Visual Studio Team Service的定期更新.VSTS是Team Foundation Server 的在线版本,微软每3周会对这个服务进行更 ...

  9. Play Framework安装和配置

    安装环境: jdk 1.7; play 1.3.1; eclipse 安装指南:http://play-framework.herokuapp.com/zh/install 安装Play Framew ...

  10. C#双色球——简单抽取中奖号码

    int[] ss = new int[6];            Random s = new Random();            Console.WriteLine("双色球随机: ...