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)——中介者模式的更多相关文章

  1. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)

    原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...

  2. 折腾Java设计模式之中介者模式

    博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...

  3. js设计模式——8.中介者模式

    js设计模式——8.中介者模式 /*js设计模式——中介者模式*/ class A { constructor() { this.number = 0; } setNumber(num, m) { t ...

  4. 设计模式之中介者模式(Mediator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程.它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  5. 【GOF23设计模式】中介者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 package com.test.mediator; /** * 同事类的接口 */ ...

  6. [设计模式] 17 中介者模式 Mediator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...

  7. 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)

    中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...

  8. 设计模式之中介者模式(Mediator )

    中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...

  9. PHP设计模式系列 - 中介者模式

    中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...

随机推荐

  1. python进阶之正则表达式

    概念: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 目的? 给定一个正则表 ...

  2. jsplumb 中文基础教程

    jsplumb 中文基础教程 https://github.com/wangduanduan/jsplumb-chinese-tutorial

  3. 轻量级卷积神经网络——MobileNet

    谷歌论文题目: MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 其他参考: CNN ...

  4. Push rejected: Push to origin/master was rejected错误解决方案

    解决方案如下: 1.切换到自己项目所在的目录,右键选择GIT BASH Here,Idea中可使用Alt+F12 2.在terminl窗口中依次输入命令: git pull git pull orig ...

  5. Java高级篇(四)——反射

    之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的.应该怎么用. 一.什么是反射 反 ...

  6. 基于密度峰值的聚类(DPCA)

    1.背景介绍 密度峰值算法(Clustering by fast search and find of density peaks)由Alex Rodriguez和Alessandro Laio于20 ...

  7. Do You Kown Asp.Net Core - 根据实体类自动创建Razor Page CURD页面模板

    Scaffolding Template Intro 我们知道在Asp.Net MVC中,如果你使用的EF的DBContext的话,你可以在vs中通过右键解决方案-添加控制器-添加包含视图的控制器,然 ...

  8. codeforces gym #102082C Emergency Evacuation(贪心Orz)

    题目链接: https://codeforces.com/gym/102082 题意: 在一个客车里面有$r$排座位,每排座位有$2s$个座位,中间一条走廊 有$p$个人在车内,求出所有人走出客车的最 ...

  9. MyBatis 传List参数 nested exception is org.apache.ibatis.binding.BindingException: Parameter 'idList' not found.

    在MyBatis传入List参数时,MyBatis报错:nested exception is org.apache.ibatis.binding.BindingException: Paramete ...

  10. Kubernetes — 为什么我们需要Pod?

    不过,我相信你在学习和使用 Kubernetes 项目的过程中,已经不止一次地想要问这样一个问题:为什么我们会需要 Pod? 是啊,我们在前面已经花了很多精力去解读 Linux 容器的原理.分析了 D ...