大家都知道无论是在家里面还是公司中,无论是通过有线还是WIFI方式连接网络,共享文件都是通过交换机作为中间媒介进行数据交换的(普通家用路由器是将路由器和交换机整合到一起了的)。这个交换机就是不同设备之间数据交换的中介者。
现在我们来假设一个简单的场景,公司里面需要多个电脑连接在一起并互相共享文件。先来看看没有交换机的情况是怎么样的。
在没有交换机(中介者)的情况下,每台电脑都要连接到其它的电脑上面。假如说有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相同,这里就不重复贴出来了。可以在文末下载代码查看。
可以看到,在没有中介者的情况下,如果一台电脑要访问其它电脑共享的文件,访问哪一个就需要实例化一个要访问的对象,这程序表达中都是一个很复杂的过程,更别说实际中的布线了。
所以说,聪明的工程师想到了一个办法,通过一个交换机(中介者)来控制数据的交换。不用的电脑设备只需要连接到交换机上面,由交换机来进行数据的传递和交换即可。
从上图可以看出来,有交换机充当中间媒介之后。每台电脑自学要将自己连接到交换机上面即可。
来看看代码实现,首先是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();
}
}
运行结果:
可以看到,中介者模式的优点就是减少了类之间的依赖,把一对多的依赖关系变成了一对一。无论是那一台电脑设备,其依赖的对象就只有交换机,很大程度上面减低了不同类之间的耦合性。
与之同时,由于不同的类都依赖于中介者,会让中介者类变得非常复杂。尽管上面交换机的例子很简单,但是有数十个设备同时依赖于交换机,且PC直接的操作更多样话时,交换机类将会变得更加的复杂和难以维护。
在面向对象编程的过程中,类之间的依赖是不可避免的。一个没有依赖的类,还有什么存在的必要呢?因此在存在多个依赖时是否要使用中介者模式要经过慎重的考虑,滥用中介者模式反而会将程序搞得更加复杂和难以维护。
在开发过程中,如果遇到以下几种情况就可以尝试使用中介者模式:
(1)N个对象之间生产了相互的依赖关系(N>2)
(2)多个对象之间的依赖行为不明确时,建议使用中介者模式。这样可以避免因为依赖变更导致类的修改(依赖变更只需要修改中介者即可)
其实在我们实际开发过程中,中介者模式非常非常常见。典型例子就是MVC(Model View Controller),Controller就是View和Model中介者。
Demo下载:点击下载
参考:
1.秦小波. 设计模式之禅. 机械工业出版社
文章评论