1.适配器模式的概念
关于适配器的概念,网上已经有很多的解释,即将一个接口转化为另外一个接口。至于为什么要转换,我们可以想象日常生活中常见的两脚插头和三脚插头。现在市场上有同时支持两脚和三脚的插头的适配器,无论是那种插脚,都能够正常通电。根据适配器模式的使用场景,我认为适配器的定义还有一个更重要,聚合不同接口类型的方法,这个在对软件系统进行改造或者对基础设计良好的系统,需要对函数执行流程进行重新整合的时候,适配器模式能够起到聚合的作用。
2.简单的适配器例子
我们有两个类,一个是两脚插头,一个是三脚插头
class DoubleInputInterface
{
public void Connect()
{
Console.WriteLine("Double Input Interface worked.");
}
}
class TrangleInputInterface
{
public void Connect()
{
Console.WriteLine("Trangle Input Interface worked.");
}
}
每个类有个Connect方法,代表连接到电源。
接下来我们有一个抽象类和一个适配器类,适配器类继承抽象类。
class InputInterface
{
public virtual void Connect(InputInterfaceType type)
{
}
}
class InputInterfaceAdapter : InputInterface
{
private readonly DoubleInputInterface doubleInputInterface = new DoubleInputInterface();
private readonly TrangleInputInterface trangleInputInterface = new TrangleInputInterface();
public override void Connect(InputInterfaceType type)
{
switch (type)
{
case InputInterfaceType.Double:
doubleInputInterface.Connect();
break;
case InputInterfaceType.Trangle:
trangleInputInterface.Connect();
break;
default:
throw new Exception("No such input interface type.");
break;
}
}
}
类的代码很简单,就不画UML图了,Adapter类持有两脚插头和三脚插头的两个引用。根据插脚的类型选择执行的方法达到适配的目的。
class Program
{
static void Main(string[] args)
{
InputInterface commonInterface = new InputInterfaceAdapter();
commonInterface.Connect(InputInterfaceType.Double);
commonInterface.Connect(InputInterfaceType.Trangle);
Console.ReadKey();
}
}
3.分析
适配器模式虽然比较好地让用户不必关注适配器内部的实现细节,但是我们发现,如果我们新增了一个连接方式我们就需要修改适配器里面的代码,从代码设计的层次来说是不合理的,那么有没有办法去改善代码呢?
首先,我们首相需要从两脚插头和三角插头抽提出一个接口(当然也可以是抽象类,其实效果是一样的,不必纠结与此)。然后我们的Apapter就可以依赖于接口,而不依赖于具体的两脚或者三角插头。这样我们在增加插头种类的时候,我们就不用修改适配器了。
其次,在调用的时候,我们先用实例化一个实例即可,用户需要了解有哪些插头种类,在用户透明性上有所牺牲,但是系统更加健壮。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AdapterPatternDemo
{
enum InputInterfaceType
{
Double,
Trangle
}
interface IInputInterface
{
void Connect();
}
class DoubleInputInterface : IInputInterface
{
public void Connect()
{
Console.WriteLine("Double Input Interface worked.");
}
}
class TrangleInputInterface : IInputInterface
{
public void Connect()
{
Console.WriteLine("Trangle Input Interface worked.");
}
}
class CommonInputInterface
{
public virtual void Connect()
{
}
}
class InputInterfaceAdapter : CommonInputInterface
{
private readonly IInputInterface inputInterface;
public InputInterfaceAdapter(IInputInterface inputInterface)
{
this.inputInterface = inputInterface;
}
public override void Connect()
{
inputInterface.Connect();
}
}
class Program
{
static void Main(string[] args)
{
IInputInterface inputInterface = new DoubleInputInterface();
CommonInputInterface commonInterface = new InputInterfaceAdapter(inputInterface);
commonInterface.Connect();
inputInterface = new TrangleInputInterface();
commonInterface = new InputInterfaceAdapter(inputInterface);
commonInterface.Connect();
Console.ReadKey();
}
}
}
运行结果是一样的:
4.扩展
在开始的时候,我们提到,适配器模式能够组合已有的功能,如果是作为组合功能的使用方式,我们可以改造适配器模式的实现方式。
class InputInterfaceAdapter : InputInterface
{
private readonly DoubleInputInterface doubleInputInterface = new DoubleInputInterface();
private readonly TrangleInputInterface trangleInputInterface = new TrangleInputInterface();
public override void Connect()
{
doubleInputInterface.Connect();
trangleInputInterface.Connect();
}
}
5.总结
设计模式的运用贵乎灵活,见招拆招,每一种设计模式有它的特长和短处,在实际开发过程中,我们只有深刻认识到某种设计模式的长处和短处才能发挥设计模式的作用,让系统更加健壮,扩展性更强。