C#设计模式(16)——中介者模式
1.中介者模式介绍
中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系,中介者使各个对象之间不需要显式地相互引用,从而降低耦合性。在开发中我们会遇到各个对象相互引用的情况,每个对象都可以和多个对象进行交互,这时将会形成复杂的一对多结构的网状结构,各个对象之间过度耦合,这样不利于类的复用和扩展。如果引入了中介者模式,各个对象都通过中介者进行交互,那么对象之间的关系将变成一对一的星型结构。
我们采用园友LearningHard玩牌的例子来理解中介者模式的用法。在现实生活中,两个人打牌,如果某个人赢了会影响到对方的状态。标准中介者模式有抽象中介者角色,具体中介者角色、抽象同事类和具体同事类四个角色,其中打牌的人都是具体的同事类的对象,算账的平台是中介者对象。如果此时不采用中介者模式实现的话,则代码实现打牌的场景如下所示:
//抽象玩家类
public abstract class AbstractCardPlayer
{
public int MoneyCount { get; set; }
public AbstractCardPlayer()
{
this.MoneyCount = ;
}
public abstract void ChangeCount(int count, AbstractCardPlayer other);
}
//玩家A类
public class PlayerA : AbstractCardPlayer
{
public override void ChangeCount(int count, AbstractCardPlayer other)
{
this.MoneyCount += count;
other.MoneyCount -= count;
}
}
//玩家B类
public class PlayerB : AbstractCardPlayer
{
public override void ChangeCount(int count, AbstractCardPlayer other)
{
this.MoneyCount += count;
other.MoneyCount -= count;
}
} class Program
{
static void Main(string[] args)
{
AbstractCardPlayer a = new PlayerA() { MoneyCount = };
AbstractCardPlayer b = new PlayerB() { MoneyCount = };
//玩家a赢了玩家b 5元
Console.WriteLine("a赢了b5元");
a.ChangeCount(, b);
Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
//玩家b赢了玩家a 10元
Console.WriteLine("b赢了a10元");
b.ChangeCount(, a);
Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
Console.ReadKey();
}
}
运行结果如下:
上边的代码满足了玩牌的功能,但是有一些缺陷:我们看到上边栗子中算钱的功能是交给赢家的a.ChangeCount(count, b)方法来实现的,这时是赢家找输家要钱 赢家a和输家b是直接通信的。当玩家比较多的时候,例如a赢了,bcde四个玩家都会输5元,那么a就要和bcde玩家都要通信(多玩家方法改成:a.ChangeCount(count,b,c,d,e)),如b赢了同理,各个玩家组成了一个复杂的通信网络,就像上边的网状图,各个玩家过度耦合。如果我们引入一个中间人来负责统一结算,赢家就可以直接找中间人结算,不必直接找所有的输家要账了,代码如下:
//抽象玩家类
public abstract class AbstractCardPlayer
{
public int MoneyCount { get; set; }
public AbstractCardPlayer()
{
this.MoneyCount = ;
}
public abstract void ChangeCount(int count, AbstractMediator mediator);
}
//玩家A类
public class PlayerA : AbstractCardPlayer
{
//通过中介者来算账,不用直接找输家了
public override void ChangeCount(int count, AbstractMediator mediator)
{
mediator.AWin(count);
}
}
//玩家B类
public class PlayerB : AbstractCardPlayer
{
public override void ChangeCount(int count, AbstractMediator mediator)
{
mediator.BWin(count);
}
}
//抽象中介者
public abstract class AbstractMediator
{
//中介者必须知道所有同事
public AbstractCardPlayer A;
public AbstractCardPlayer B;
public AbstractMediator(AbstractCardPlayer a,AbstractCardPlayer b)
{
A = a;
B = b;
}
public abstract void AWin(int count);
public abstract void BWin(int count);
}
//具体中介者
public class Mediator : AbstractMediator
{
public Mediator(AbstractCardPlayer a,AbstractCardPlayer b):base(a,b){}
public override void AWin(int count)
{
A.MoneyCount += count;
B.MoneyCount -= count;
}
public override void BWin(int count)
{
A.MoneyCount -= count;
B.MoneyCount += count;
}
}
class Program
{
static void Main(string[] args)
{
AbstractCardPlayer a = new PlayerA() { MoneyCount = };
AbstractCardPlayer b = new PlayerB() { MoneyCount = };
AbstractMediator mediator = new Mediator(a, b);
//玩家a赢了玩家b 5元
Console.WriteLine("a赢了b5元");
a.ChangeCount(, mediator);
Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
//玩家b赢了玩家a 10元
Console.WriteLine("b赢了a10元");
b.ChangeCount(, mediator);
Console.WriteLine($"玩家a现在有{a.MoneyCount}元");
Console.WriteLine($"玩家b现在有{b.MoneyCount}元");
Console.ReadKey();
}
}
运行结果和不用中介者的例子一致。我们可以看到中介者模式降低了各个同事对象的耦合,同事类之间不用直接通信,直接找中介者就行了,但是中介者模式并没有降低业务的复杂度,中介者将同事类间的复杂交互逻辑从业务代码中转移到了中介者类的内部。标准中介者模式有抽象中介者角色,具体中介者角色、抽象同事类和具体同事类四个角色,在实际开发中有时候没必要对具体中介者角色和具体用户角色进行抽象(如联合国作为一个中介者,负责调停各个国家纠纷,但是没必要把单独的联合国抽象成一个抽象中介者类;上边例子的抽象玩家类和抽象中介者类都是没必要的),我们可以根据具体的情况来来选择是否使用抽象中介者和抽象用户角色。
2.小结
1.上边例子的类图
中介者模式优点:
1 降低了同事类交互的复杂度,将一对多转化成了一对一;
2 各个类之间的解耦;
3 符合迪米特原则。
中介者模式缺点:
1 业务复杂时中介者类会变得复杂难以维护。
参考文献
[1] http://www.runoob.com/design-pattern/mediator-pattern.html
[2] http://www.cnblogs.com/zhili/p/MediatorPattern.html
C#设计模式(16)——中介者模式的更多相关文章
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- js设计模式——8.中介者模式
js设计模式——8.中介者模式 /*js设计模式——中介者模式*/ class A { constructor() { this.number = 0; } setNumber(num, m) { t ...
- 设计模式之中介者模式(Mediator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程.它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 【GOF23设计模式】中介者模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 package com.test.mediator; /** * 同事类的接口 */ ...
- [设计模式] 17 中介者模式 Mediator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...
- 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)
中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...
- 设计模式之中介者模式(Mediator )
中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...
- PHP设计模式系列 - 中介者模式
中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...
随机推荐
- c/c++ 网络编程 使用getaddrinfo的单纯UDP 通信
网络编程 使用getaddrinfo的单纯UDP 1,UDP发送端 2,UDP接收端 UDP发送端: #include <stdio.h> #include <unistd.h> ...
- React.js开发的基本配置(配了两天)
记录下心酸的过程: 1.安装npm 安装node.js,这时候你就可以使用npm了. 因为官方的源下载npm的包比较慢,所以可以用淘宝的源,这时候使用nrm来进行npm源的切换 在cmd中执行 npm ...
- grep -v、-e、-E
在Linux的grep命令中如何使用OR,AND,NOT操作符呢? 其实,在grep命令中,有OR和NOT操作符的等价选项,但是并没有grep AND这种操作符.不过呢,可以使用patterns来模拟 ...
- 位(Bit)与字节(Byte)
字 word 字节 byte 位 bit 字长是指字的长度 1字=2字节(1 word = 2 byte) 1字节=8位(1 byte = 8bit) 一个字的字长为16 一个字节的字长是8 bps ...
- Example of DenseCRF with non-RGB data
本笔记本通过一个示例说明如何在非rgb数据上使用DenseCRFs.同时,它将解释基本概念并通过一个示例进行演示,因此即使您正在处理RGB数据,它也可能是有用的,不过也请查看PyDenseCRF's ...
- zabbix优化,配合文件,zabbix_get命令
一.配置文件优化 server端配置文件添加如下 StartPollers=160 #zabbix_server的进程数 StartPollersUnreacheable=80 #默认情况下,ZABB ...
- UI Automator 常用 API 整理
主要类: import android.support.test.uiautomator.UiDevice; 作用:设备封装类,测试过程中获取设备信息和设备交互. import android.sup ...
- UOJ129 NOI2015 寿司晚宴 数论、状压DP
传送门 数论题\(n \leq 500\)肯定是什么暴力算法-- 注意到每一个数\(> \sqrt{n}\)的因子最多只有一个,这意味着\(> \sqrt{n}\)的因子之间是独立的,而只 ...
- 基于 WebGL 3D 的 HTML5 档案馆可视化管理系统
前言 档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能.为企事业单位的档案现代化管理,提供完整的解决方案,档 ...
- 爬虫基础(四)-----MongoDB的使用
------------------------------------------------------------------------摆脱穷人思维 <四> :减少无意义的频繁决策 ...