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. python3 dict(字典)

    clear(清空字典内容) stu = { 'num1':'Tom', 'num2':'Lucy', 'num3':'Sam', } print(stu.clear()) #输出:None copy( ...

  2. 重装助手教你如何在Windows 10中更改您的帐户名称

    当您设置新的Win10免费下载 PC时,您选择用户名的部分可能会让您措手不及.如果是这种情况,您可以选择弹出头部的第一件事或者您打算稍后更改的随机和临时事物.但令人惊讶的是,在Windows 10中更 ...

  3. git冲突解决办法合集

    一 换行符CRLF错误解决办法 1 错误产生原因 不同的操作系统使用的换行符是不一样的. unix/linux使用的是LF,max后期也采用了LF,但在windows一直采用的CRLF(回车)换行符. ...

  4. 爬虫系列二(数据清洗--->xpath解析数据)

    一 xpath介绍 XPath 是一门在 XML 文档中查找信息的语言.XPath 用于在 XML 文档中通过元素和属性进行导航. XPath 使用路径表达式在 XML 文档中进行导航 XPath 包 ...

  5. WINFORM因为 线程崩溃

    1.如果WinForm程序中使用了线程,而线程调用的代码中会抛出异常,该异常没有任何Try块处理.就会导致程序从主线程中跳出,导致WinForm程序突然崩溃性关闭.2.程序读写某些外部资源,比如数据库 ...

  6. Django框架【form组件】

    from django.shortcuts import render,redirect # Create your views here. from .models import * from dj ...

  7. Autofs自动挂载探讨

    Autofs介绍: mount是用来挂载文件系统的,可以在系统启动的时候挂载也可以在系统启动后挂载.对于本地固定设 备,如硬盘可以使用mount挂载:而光盘.软盘.NFS.SMB等文件系统具有动态性, ...

  8. (golang)HTTP基本认证机制及使用gocolly登录爬取

    内网有个网页用了HTTP基本认证机制,想用gocolly爬取,不知道怎么登录,只好研究HTTP基本认证机制 参考这里:https://www.jb51.net/article/89070.htm 下面 ...

  9. nodeJS之crypto模块md5和Hmac加密

    nodeJS之crypto模块md5和Hmac加密 原文地址:https://www.cnblogs.com/tugenhua0707/p/9128690.html 在nodejs中,可以使用cryp ...

  10. 对分类型变量,进行编码处理——pd.get_dummies()、LabelEncoder()、oneHotEncoder()

    背景: 在拿到的数据里,经常有分类型变量的存在,如下: 球鞋品牌:Nike.adidas. Vans.PUMA.CONVERSE 性别:男.女 颜色:红.黄.蓝.绿 However,sklearn大佬 ...