概述:
在软件开发过程中,我们要经常要复用我们以前开发的一些“现存对象”,但是这些“现存对象”并不能满足我们新的应用环境。怎样才能良好的复用这些对象,以满足我们的应用环境,这就是适配器(Adapter)所要解决的问题。
意图:
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
——《设计模式》GOF
生活中的例子:
![](https://i-blog.csdnimg.cn/blog_migrate/a2e8d2bcea43744a1e697cfb957c5dfe.gif)
类结构图:
![](https://i-blog.csdnimg.cn/blog_migrate/44c953eaa756ae71af16f45ca07d738c.png)
代码实现:
public interface ITarget
{
void GetPower();
}
// 220V电源类;
public class Power
{
// 从电源中得到220V的电压
public void GetPoer220V()
{
Console.WriteLine("这个是220V的电压!")
}
}
// 适配器类(充电器)
public class Adapter : Power, ITarget
{
// 得到想要电压;
public void GetPower()
{
this.GetPoer220V();
Console.WriteLine("得到手机的充电电压!");
}
}
//使用
class Program
{
// 这里相当于是手机;
static void Main(string[] args)
{
Console.Write("手机:");
ITarget Target = new Adapter();
Target.GetPower();
Console.Read();
}
}
特点:它使用多继承的方式来实现,我们只需要调用得到电压(GetPower())方法,由充电器(Adapter)去将220V的电压转成我们需要的电压供我们使用。
![](https://i-blog.csdnimg.cn/blog_migrate/4594226efc5ff7fa6ced4f3c63db4ed9.gif)
类结构图:
![](https://i-blog.csdnimg.cn/blog_migrate/d3ec3e1b5dd0ba26f74bd510094639ed.png)
代码实现:
public interface ITarget
{
void GetPower();
}
// 220V电源类
public class Power
{
// 得到220V电压;
public void GetPoer220V()
{
Console.WriteLine("在这是220V的电压!");
}
}
// 适配器类(充电器)
public class Adapter : ITarget
{
Power power;
// 适配器的构造函数;
public Adapter(Power power)
{
this.power = power;
}
// 得到想要的电压;
public void GetPower()
{
power.GetPoer220V();
Console.WriteLine("得到手机的充电电压!");
}
}
//调用:
class Program
{
// 这里相当于手机;
static void Main(string[] args)
{
Console.Write("手机:");
Power power=new Power();
ITarget Target = new Adapter(power);
Target.GetPower();
Console.Read();
}
}
总结:
对于此例子,我们要对手机充电,电力部门不可能给我们提供我们需要的电压,有时候也不一定满足我们的需要,这个就是要我们自己进行转换,这就用到适配器(Adapter)。
对软件系统中,如果要复用以前的“现存对象”,但是这些对象所提供的接口并不一定能适应我们的新环境,我们就要对其转换成我们需要的接口,来供我们调用。
要点:
2.Adapter模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。适用性:
在以下各种情况下使用适配器模式:
1.系统需要使用现有的类,而此类的接口不符合系统的需要。
2.想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。
3.(对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。
Adapter在.NET中的应用:
1. 在.NET中复用COM对象
-COM对象不符合.NET对象接口
-使用tlbimp.exe创建一个Rumtime Callable Wrapper(RCW)使其符合.NET对象接口
2..NET数据访问类(Adapter变体)
-各种数据库并没有提供DataSet接口
-使用DbDataAdapter可以将任何各数据库访问/存取适配到一个DataSet对象上。
在ADO.NET中,对于我们从数据库中取出的数据都要放到一个DataSet中,不管你是Access的数据库,还是SQL的数据库,或者是Oracle的数据库都要放到DataSet中。.NET中并没有提供如:SqlDataSet、OleDbDataSet、OracleDataSet等,它只提供了一种DataSet就是用SqlDataAdapte等去填充数据;为什么这一个DataSet能存放不同的数据呢?就是有这些适配器来适配。
DataAdapter结构图:
3.集合类中对现有对象的排序(Adapter变体)
-现有对象未实现IComparable接口
-实现一个排序适配器(继承IComparable接口),然后在其Compare方法中对两个对象进行比较。