夸克之书

  • 首页
  • 科普
  • 笔记
  • .NET/C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. .NET/C#
  3. 正文

23种常见的设计模式(8):中介者模式

2020-02-04 2657点热度 1人点赞 0条评论

大家都知道无论是在家里面还是公司中,无论是通过有线还是WIFI方式连接网络,共享文件都是通过交换机作为中间媒介进行数据交换的(普通家用路由器是将路由器和交换机整合到一起了的)。这个交换机就是不同设备之间数据交换的中介者。

现在我们来假设一个简单的场景,公司里面需要多个电脑连接在一起并互相共享文件。先来看看没有交换机的情况是怎么样的。

%title插图%num
没有交换机的情况(网状结构)

在没有交换机(中介者)的情况下,每台电脑都要连接到其它的电脑上面。假如说有N台电脑的话,工程量可想而知。我们用代码来实现以下。

首先是每台电脑都需要共享文件,和获取其它电脑文件的方法。我们来定义一个IPC的接口来对这两个方法进行一个约束,每台电脑都需要实现这两个方法。

interface IPC
{
    string Name { get; }

    string Share(string guest);

    void Get();
}

然后已PC_A为例,来实现PC_A中的方法。

class PC_A : IPC
{
    /// <summary>
    /// PC名称
    /// </summary>
    public string Name => this.GetType().Name;

    /// <summary>
    /// 共享文件方法
    /// </summary>
    /// <param name="guest">请求获取文件PC名称</param>
    /// <returns></returns>
    public string Share(string guest)
    {
        if (string.IsNullOrEmpty(guest))
        {
            throw new Exception("访客不能为空。");
        }
        return $"访客【{guest}】,这是{Name}共享的资源。";
    }

    /// <summary>
    /// 获取其它电脑共享文件方法
    /// </summary>
    public void Get()
    {
        Console.WriteLine($"{Name}:");
        PC_A a = new PC_A();
        PC_B b = new PC_B();
        PC_C c = new PC_C();
        Console.WriteLine(a.Share(Name));
        Console.WriteLine(b.Share(Name));
        Console.WriteLine(c.Share(Name));
        Console.WriteLine();
    }
}

PC_B、PC_C代码和PC_A相同,这里就不重复贴出来了。可以在文末下载代码查看。

可以看到,在没有中介者的情况下,如果一台电脑要访问其它电脑共享的文件,访问哪一个就需要实例化一个要访问的对象,这程序表达中都是一个很复杂的过程,更别说实际中的布线了。

所以说,聪明的工程师想到了一个办法,通过一个交换机(中介者)来控制数据的交换。不用的电脑设备只需要连接到交换机上面,由交换机来进行数据的传递和交换即可。

%title插图%num
由交换机负责不同设备之间的数据交换(星型网络结构)

从上图可以看出来,有交换机充当中间媒介之后。每台电脑自学要将自己连接到交换机上面即可。

来看看代码实现,首先是Switcher中介者类。

class Switcher
{
    PC_A a = new PC_A();

    PC_B b = new PC_B();

    PC_C c = new PC_C();

    /// <summary>
    /// 获取共享的文件数据
    /// </summary>
    /// <param name="guest">访问者</param>
    /// <param name="dist">访问对象</param>
    /// <returns></returns>
    public string Get(string guest,string dist)
    {
        switch (dist)
        {
            case nameof(PC_A):
                return a.Share(guest);
            case nameof(PC_B):
                return b.Share(guest);
            case nameof(PC_C):
                return c.Share(guest);
            default:
                throw new Exception("错误,禁止访问。");
        }
    }
}

PC_A通过交换机(中介者)来访问其它其它电脑的共享。

class PC_A : IPC
{
    /// <summary>
    /// PC名称
    /// </summary>
    public string Name => this.GetType().Name;

    /// <summary>
    /// 共享文件方法
    /// </summary>
    /// <param name="guest">请求获取文件PC名称</param>
    /// <returns></returns>
    public string Share(string guest)
    {
        if (string.IsNullOrEmpty(guest))
        {
            throw new Exception("访客不能为空。");
        }
        return $"访客【{guest}】,这是{Name}共享的资源。";
    }

    /// <summary>
    /// 获取其它电脑共享文件方法
    /// </summary>
    public void Get()
    {
        Switcher mediator = new Switcher();

        Console.WriteLine($"{this.GetType().Name}:");
        Console.WriteLine(mediator.Get(this.GetType().Name, nameof(PC_A)));
        Console.WriteLine(mediator.Get(this.GetType().Name, nameof(PC_B)));
        Console.WriteLine(mediator.Get(this.GetType().Name, nameof(PC_C)));
        Console.WriteLine();
    }
}

运行结果:

%title插图%num
中介者模式运行截图

可以看到,中介者模式的优点就是减少了类之间的依赖,把一对多的依赖关系变成了一对一。无论是那一台电脑设备,其依赖的对象就只有交换机,很大程度上面减低了不同类之间的耦合性。

与之同时,由于不同的类都依赖于中介者,会让中介者类变得非常复杂。尽管上面交换机的例子很简单,但是有数十个设备同时依赖于交换机,且PC直接的操作更多样话时,交换机类将会变得更加的复杂和难以维护。

%title插图%num
中介者模式通用类图

在面向对象编程的过程中,类之间的依赖是不可避免的。一个没有依赖的类,还有什么存在的必要呢?因此在存在多个依赖时是否要使用中介者模式要经过慎重的考虑,滥用中介者模式反而会将程序搞得更加复杂和难以维护。

在开发过程中,如果遇到以下几种情况就可以尝试使用中介者模式:

(1)N个对象之间生产了相互的依赖关系(N>2)
(2)多个对象之间的依赖行为不明确时,建议使用中介者模式。这样可以避免因为依赖变更导致类的修改(依赖变更只需要修改中介者即可)

其实在我们实际开发过程中,中介者模式非常非常常见。典型例子就是MVC(Model View Controller),Controller就是View和Model中介者。

Demo下载:点击下载

参考:

1.秦小波. 设计模式之禅. 机械工业出版社

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2020-12-13

管理员

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论
放松一下
https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
分类
  • .NET/C#
  • Linux
  • 树莓派
  • 物联网
  • 科普
  • 笔记
  • 算法
  • 默认
最新 热点 随机
最新 热点 随机
Windows Server 2022安装Intel I225-V驱动 System.Text.Json与Newtonsoft.Json Json序列化与反序列化性能对比 R86S散热改造 Windows移除多余输入法'Unknown Locale (qaa-Latn)' 【算法】具有层级关系的城市,例如"中国 广州","中国 浙江 杭州" 一个 List 最后应该是转成树状图输出 树莓派安装Golang环境
Windows Server 2022安装Intel I225-V驱动
ASP.NET Core Code First使用MySQL以及初始化默认数据 免费本地解析域名(locallocal.cn),支持HTTPS OpenWrt配置SmartDNS 基于CURL的HTTP请求代码(C语言) 单机Docker搭建FastDFS MySQL ONLY_FULL_GROUP_BY报错
最近评论
afirefish 发布于 2 个月前(11月28日) 非常感谢,非常棒!
》随缘《 发布于 3 个月前(11月20日) 最新【一键处理】方法: https://github.com/MrXhh/VSTools/rele...
管理员 发布于 8 个月前(06月22日) emmmm....服务器好一点???
wking 发布于 9 个月前(05月23日) 请问贵博客是怎么优化的,网页响应速度非常快。我博客同样的WordPress和kratos主题,但点一...
去月球 发布于 1 年前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
书签
  • 打赏
  • 毒鸡汤
  • 米店
  • 金鱼直播间

COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备15036129号-9

登录
注册|忘记密码?