(七)中介者模式-C++实现
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其解耦合松散而且可以独立地改变他们之间的交互。
中介者模式适合于 系统中不希望对象之间直接交互,即不希望类之间相互包含,成为朋友。
中介者模式中有四种角色:
(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++实现的更多相关文章
- 23种设计模式--中介者模式-Mediator Pattern
一.中介者模式的介绍 中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...
- 设计模式--中介(Mediator)模式
时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...
- 设计模式---接口隔离模式之中介者模式(Mediator)
一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...
- 行为型模式(五) 中介者模式(Mediator)
一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...
- MediatorPattern(中介者模式)
/** * 中介者模式 * @author TMAC-J * 研究了这么多设计模式,觉得无非就是几点: * 1.若两个类有耦合关系,设立一个中间类,处理两个类的关系,把两个类的耦合降低 * 2.面向接 ...
- C#设计模式-中介者模式
在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 一. 中介者(Mediator)模式 从 ...
- php实现设计模式之 中介者模式
<?php /* * 中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ /* * 以一个同学qq群为例说明, ...
- 轻松掌握:JavaScript代理模式、中介者模式
代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
随机推荐
- [deviceone开发]-模仿Zaker的示例
一.简介 这个示例模仿zaker这个App,主要的界面基本都完成,用到了各种deviceone提供的ui组件,比如GridView,ListView,ScrollView,ViewShower等等.初 ...
- sql2008“备份集中的数据库备份与现有的xxx数据库不同”解决方法
因为是在另一台电脑对同名数据库做的备份,用常规方法还原,提示不是相同数据库,不让还原,在网上找到下面的方法解决了: 一.打开sql企业管理器,新建查询 执行以下SQL代码: RESTORE DATAB ...
- JavaScript基础19——innerHTML示例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js一些代码方法
概要 1.替换json对象中属性值(包括子对象) 2.兼容多个$库写法(zepto与jquery) 3.闭包保持变量的做法 详情 1.替换json对象中属性值(包括子对象) //替换json对象属性值 ...
- swift学习笔记之-扩展(Extensions)
//扩展(Extensions) import UIKit /*扩展(Extensions):扩展 就是为一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩 ...
- js 中{},[]中括号,大括号使用详解
一.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数. 如:var LangShen = {"Name":"Langshen",&qu ...
- Android 6.0权限全面详细分析和解决方案
原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/483711 ...
- iOS block从零开始
iOS block从零开始 在iOS4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调. block的结构 先来一段简单的代码看看: void ...
- C++语言-05-三大特性
概述 C++ 是面向对象的语言,具备 OOP 的基本特性. 封装 概念 将数据和操作数据的函数绑定在一起 作用 避免受到外界的干扰和误用,确保了安全 与封装相关的概念 数据抽象 仅向用户暴露接口而把具 ...
- javascript中,对于this指向的浅见
# this的指向在函数创建的时候确定不了.只有在执行的时候,才可以确定. ## 1 . 这里的this指向window window.fn(); 所以this.user是undefined func ...