设计模式---接口隔离模式之中介者模式(Mediator)
一:概念
在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互。Mediator对象起到控制器的作用
二:动机
在软件构建的过程中,经常出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到了一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可以使用“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间额紧耦合引用关系,从而更好地抵御变化。
三:模式定义
用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各个对象不需要显示的相互引用(编译时依赖 -> 运行时依赖),从而使其耦合松散(管理变化),而且可以独立的改变他们之间的交互。 --《设计模式》Gof
四:结构
五:与Facade模式比较
Facade是系统外与系统内之间的隔离,而中介者Mediator解决的是系统内中各个对象之间的隔离。
多个对象,呈现复杂的引用关系时使用Mediator模式
六:类图
七:要点总结
(一)将多个对象间复杂的关联关系解耦,Mediator模式将多个对象间的控制逻辑进行集中管理(定义一套调用机制的协议),变“多个对象互相关联”为“多个对象和一个中介者关联”,简化了系统的维护,抵御了可能的变化。
(二)随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。
(三)Facade模式是解耦系统间(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。
八:案例实现
(一)反例:类的紧密性抢,需要解耦合
#include <iostream>
#include <string>
using namespace std; class Person
{
protected:
string m_name;
int m_sex;
int m_condition;
public:
Person(string name, int sex, int condit)
{
m_name = name;
m_sex = sex;
m_condition = condit;
} string getName()
{
return m_name;
} int getSex()
{
return m_sex;
} int getCondit()
{
return m_condition;
} virtual void getParter(Person* p) = ; //接口获取伴侣
}; class Man :public Person
{
public:
Man(string name, int sex, int condit) :Person(name, sex, condit)
{
} virtual void getParter(Person* p)
{
if (this->getSex() == p->getSex())
{
cout << "no I`m don't same sex" << endl;
}
else
{
if (this->getCondit() == p->getCondit())
cout << this->getName() << " matching with " << p->getName() << endl;
else
cout << this->getName() << " not matching with " << p->getName() << endl;
}
}
}; class Woman :public Person
{
public:
Woman(string name, int sex, int condit) :Person(name, sex, condit)
{
} virtual void getParter(Person* p)
{
if (this->getSex() == p->getSex())
{
cout << "no I`m don't same sex" << endl;
}
else
{
if (this->getCondit() == p->getCondit())
cout << this->getName() << " matching with " << p->getName() << endl;
else
cout << this->getName() << " not matching with " << p->getName() << endl;
}
}
}; void main()
{
Woman *w1 = new Woman("xioafang", , );
Man* m1 = new Man("zhangsan", , );
Man* m2 = new Man("lisi", , ); w1->getParter(m1);
w1->getParter(m2);
m1->getParter(m2); delete w1;
delete m2;
delete m1; system("pause");
return;
}
具体子类向关联,紧密性太强
(二)使用中介者模式进行解耦合
1.实现系统内对象
#include <iostream>
#include <string>
using namespace std; class Mediator; class Person
{
protected:
string m_name;
int m_sex;
int m_condition;
Mediator* m_m;
public:
Person(string name, int sex, int condit,Mediator* m)
{
m_name = name;
m_sex = sex;
m_condition = condit;
m_m = m;
} string getName()
{
return m_name;
} int getSex()
{
return m_sex;
} int getCondit()
{
return m_condition;
} Mediator* getMediator()
{
return m_m;
} virtual void getParter(Person* p) = ; //接口获取伴侣
}; class Man :public Person
{
public:
Man(string name, int sex, int condit,Mediator* m) :Person(name, sex, condit,m)
{
} virtual void getParter(Person* p)
{
//使用中介者来实现判断
this->getMediator()->setMan(this);
this->getMediator()->setWoman(p);
this->getMediator()->getPartner();
}
}; class Woman :public Person
{
public:
Woman(string name, int sex, int condit, Mediator* m) :Person(name, sex, condit,m)
{
} virtual void getParter(Person* p)
{
//使用中介者来实现判断
this->getMediator()->setWoman(this);
this->getMediator()->setMan(p);
this->getMediator()->getPartner();
}
};
2.实现中介者
class Mediator
{
private:
Person* pMan; //中介者Mediator解决的是系统内中各个对象之间的隔离
Person* pWoman; //所以我们要对所有要处理的类设置一个指针,实现双向关联(上面Person基类指向了中介者,代表Man和Woman都指向了,现在要中介者执行Man和Woman)
public:
Mediator()
{
pMan = NULL;
pWoman = NULL;
} void setWoman(Person* p)
{
pWoman = p;
} void setMan(Person* p)
{
pMan = p;
} void getPartner()
{
if (pMan->getSex() == pWoman->getSex())
{
cout << "no I`m don't same sex" << endl;
}
else
{
if (pMan->getCondit() == pWoman->getCondit())
cout << pMan->getName() << " matching with " << pWoman->getName() << endl;
else
cout << pMan->getName() << " not matching with " << pWoman->getName() << endl;
}
}
};
3.中介者测试
void main()
{
Mediator* mediator = new Mediator();
Woman *w1 = new Woman("xioafang", , ,mediator);
Man* m1 = new Man("zhangsan", , ,mediator);
Man* m2 = new Man("lisi", , ,mediator); w1->getParter(m1);
w1->getParter(m2);
m1->getParter(m2); delete w1;
delete m2;
delete m1;
delete mediator; system("pause");
return;
}
#include <iostream>
#include <string>
using namespace std; class Mediator; class Person
{
protected:
string m_name;
int m_sex;
int m_condition;
Mediator* m_m;
public:
Person(string name, int sex, int condit,Mediator* m)
{
m_name = name;
m_sex = sex;
m_condition = condit;
m_m = m;
} string getName()
{
return m_name;
} int getSex()
{
return m_sex;
} int getCondit()
{
return m_condition;
} Mediator* getMediator()
{
return m_m;
} virtual void getParter(Person* p) = ; //接口获取伴侣
}; class Mediator
{
private:
Person* pMan; //中介者Mediator解决的是系统内中各个对象之间的隔离
Person* pWoman; //所以我们要对所有要处理的类设置一个指针,实现双向关联(上面Person基类指向了中介者,代表Man和Woman都指向了,现在要中介者执行Man和Woman)
public:
Mediator()
{
pMan = NULL;
pWoman = NULL;
} void setWoman(Person* p)
{
pWoman = p;
} void setMan(Person* p)
{
pMan = p;
} void getPartner()
{
if (pMan->getSex() == pWoman->getSex())
{
cout << "no I`m don't same sex" << endl;
}
else
{
if (pMan->getCondit() == pWoman->getCondit())
cout << pMan->getName() << " matching with " << pWoman->getName() << endl;
else
cout << pMan->getName() << " not matching with " << pWoman->getName() << endl;
}
}
}; class Man :public Person
{
public:
Man(string name, int sex, int condit,Mediator* m) :Person(name, sex, condit,m)
{
} virtual void getParter(Person* p)
{
//使用中介者来实现判断
this->getMediator()->setMan(this);
this->getMediator()->setWoman(p);
this->getMediator()->getPartner();
}
}; class Woman :public Person
{
public:
Woman(string name, int sex, int condit, Mediator* m) :Person(name, sex, condit,m)
{
} virtual void getParter(Person* p)
{
//使用中介者来实现判断
this->getMediator()->setWoman(this);
this->getMediator()->setMan(p);
this->getMediator()->getPartner();
}
}; void main()
{
Mediator* mediator = new Mediator();
Woman *w1 = new Woman("xioafang", , ,mediator);
Man* m1 = new Man("zhangsan", , ,mediator);
Man* m2 = new Man("lisi", , ,mediator); w1->getParter(m1);
w1->getParter(m2);
m1->getParter(m2); delete w1;
delete m2;
delete m1;
delete mediator; system("pause");
return;
}
全部代码
设计模式---接口隔离模式之中介者模式(Mediator)的更多相关文章
- C#设计模式学习笔记:(17)中介者模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7966240.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第五个模式--中 ...
- Java进阶篇设计模式之十 ---- 访问者模式和中介者模式
前言 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern).本篇则来学习下行为型模式的两个模式,访问者模式(Visito ...
- Java设计模式之十 ---- 访问者模式和中介者模式
前言 2018年已经过去,新的一年工作已经开始,继续总结和学习Java设计模式. 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator P ...
- Java 设计模式系列(十七)中介者模式
Java 设计模式系列(十七)中介者模式 用一个中介对象来封装一系列的对象交互.中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互 一.中介者模式结构 Media ...
- 【设计模式】 模式PK:门面模式VS中介者模式
1.概述 门面模式为复杂的子系统提供一个统一的访问界面,它定义的是一个高层接口,该接口使得子系统更加容易使用,避免外部模块深入到子系统内部而产生与子系统内部细节耦合的问题.中介者模式使用一个中介对象来 ...
- 设计模式之第19章-中介者模式(Java实现)
设计模式之第19章-中介者模式(Java实现) “测试妹纸找你,你的代码出问题了.”“美工妹纸让你看看界面怎么样.”身为程序员总要和各种人打交道,但是如果再分为前端.后端工程师的话,那么关系就会错综复 ...
- 轻松掌握:JavaScript代理模式、中介者模式
代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...
- 设计模式---接口隔离模式之门面模式(Façade)
前提:接口隔离模式 在组建构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接接口(稳定的),来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式: 门面模 ...
- 我所理解的设计模式(C++实现)——中介者模式(Mediator Pattern)
概述: 假设我们开发一个图片处理软件,里面肯定包括很多相关功能,比如说剪切,旋转,滤镜,美化等等,而我们这些功能所要处理的对象是固定的,就是我们所显示的那张图片.但是我们不能把所有的功能罗列到一个ta ...
随机推荐
- 二:C#对象、集合、DataTable与Json内容互转示例;
导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型: 二:C#对象.集合.DataTable与Json内容互转示例: ...
- P1164 小A点菜
原题链接 https://www.luogu.org/problemnew/show/P1164 此题是一道简单的动规问题 才学两天不是很熟练,我苦思冥想看着题解终于想出来了. 主要的思路如下: 我们 ...
- LOJ6432 [PKUSC2018] 真实排名 【组合数】
题目分析: 做三个指针然后预处理阶乘就行. 题目代码: #include<bits/stdc++.h> using namespace std; ; ; int n,k; struct n ...
- 洛谷P1501 Tree II
LCT 还是LCT的板子,下放标记和那道线段树2一样,先放乘..之前用char忘记getchar,调了好久... 注意开long long!! #include <bits/stdc++.h&g ...
- python中的logging模块学习
Python的logging模块 Logging的基本信息: l 默认的情况下python的logging模块打印到控制台,只显示大于等于warning级别的日志 l 日志级别:critical ...
- 常用 git 基础命令
git config --global credential.helper store记住密码 git config user.name xxx配置帐号 git config user.email x ...
- 【HDU - 4342】History repeat itself(数学)
BUPT2017 wintertraining(15) #8C 题意 求第n(n<2^32)个非完全平方数m,以及\(\sum_{i=1}^m{\lfloor\sqrt i\rfloor}\) ...
- LA3490 Generator(KMP + 高斯消元)
题意 一开始给你一个长为 \(S\) 的字符串. 从空串开始,不断在后面添加一个 \([A, A + n]\) 的一个字符. 第一次包含 \(S\) 的时候会停止添加.问期望的添加次数. 有 \(T\ ...
- 763. Partition Labels
我一开始看数据范围很小,没怎么想就直接暴力了. 暴力的思路是: 对于每一段S的前缀,这个前缀中的每一个字母都不应该在前缀的补集中出现,所以直接循环i:0 to S.length然后对于每一次循环,再循 ...
- HDU6341 Let Sudoku Rotate (杭电多校4J)
给一个由4*4个4*4的小格组成数独,这些数独是由一个块逆时针旋转得来的,所以要还原的话就模拟出顺时针的过程,先把里面的字母转化成数字,然后从第一个块开始枚举,每个dfs和之前枚举的已经满足条件的块, ...