提到适配器,我们想到最多的是电源适配器。在不改变电厂电压和手机接收充电电压值的情况下,如何把220V的电压变化为手机能够接受的电压,这就需要用到适配器。
编程中同样存在这样的情况,比如现在我们有两个模块的代码,希望在不改变两个模块代码的情况下使它们两个能够协调工作,那就需要用到适配器来起到”桥梁“的作用。
适配器有两种:1、对象适配器:适配器与适配者(被适配的对象)之间是关联的关系 2、类适配器:适配器与适配者之间是继承的关系。
下面重点讲常用的对象适配器模式。
一图胜千言,上图!
其中Target是客户操作的类,它可以是一个接口,或是一个抽象类,也可以是一个具体类。(图中暂且用继承代替)
我们的目的是利用适配器,是先Target与Adaptee的适配,是用户只通过Target便能使用Adaptee的功能,而不需要知道Adaptee中的实现。
注意,在对象适配器模式中,适配器与适配者是关联的关系,这里关联关系的箭头未标明,应该是适配器中包含了适配者的对象。
在看一段代码,大家就基本清楚了。
这是一段关于适配两个算法代码库的代码。
目标类(用户操作的类)
interface DataOperation
{
public int[] sort(int array[]);//排序方法
public int search(int array[],int key);//查找方法
}
适配器类
public class OperationAdapter implements DataOperation
{
private QuickSort quicksort;
private BinarySearch binarysearch;
public OperationAdapter(QuickSort sortObj,BinarySearch searchObj)//构造方法,参数传入适配者类
{
quicksort=sortObj;
binarysearch=searchObj;
}
public int[] sort(int array[])
{
return quicksort.quickSort(array);
}
public int search(int array[],int key)
{
return binarysearch.binarySearch(array, key);
}
}
适配者类
class QuickSort//适配者类
{
public int[] quickSort(int array[])
{
}
}
class BinarySearch//适配者类
{
public int binarySearch(int array[],int key)
{
}
}
适配者中的代码可以忽略(一个实现快速排序,一个实现二分搜索)。
重点是适配器的代码:首先适配其中有两个适配者类的成员,并且在适配者构造函数中通过传入参数的方式进行初始化。又因为适配器是继承了目标接口的,所以他就需要实现其中的抽象方法,而抽象方法的具体实现则是通过调用适配器中适配者对象的方法实现的。
客户端使用时,只需要先创建两个代码库对象实例,再通过创建适配器的实例(通过参数传入代码库对象),再调用适配器的相应方法即可。
最后简单地说一下类适配器,其中适配器与适配者的关系式继承(或实现),所以对于java,c#等不支持多继承的语言来说,当适配者是一个类而不是一个接口时,类适配器模式的使用就会受到限制。