设计模式之适配器模式
适配器模式(Adapter),其含义是将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作了。因此适配器的主要作用就是完成旧接口到新接口的转换;将“既有系统“进行封装,逻辑上客户程序应该不知道”既有系统“的存在,将变化隔离在适配器部分;如果客户程序需要迁移,仅需要在适配器部分进行修改。
其适用性:
你想使用一个已经存在的类,而它的接口不符合你的要求,
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可以不一定兼容的类)协同工作,
你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
实现适配一般有两种方式:一种是通过多重继承让适配器类具有既有类型的特点,同时也满足新接口的需要,一般称为类适配器;另一种是在适配器中保存一个队既有类型的引用,它自身按照客户程序的要求,实现新接口,这种方式被称为对象适配器。类适配器和对象适配器的结构如下,使用时应优先使用对象适配器:
类适配器:
对象适配器:
可见,类适配器和对象适配器的最大的区别就是对Adaptee,也就是我们通常说的母接口的使用,是通过继承获得操作,还是通过关联使用操作。在C++实现适配器类时,Adapter类应该采用公有方式继承Target类,并且用私有方式继承Adaptee类,因此Adapter类应该是Target的子类型,但不是Adaptee的子类型。
两种的不同如下:
package org.designpattern.structural.adapterclass;
public void request();
}
public void specificRequest(){
System.out.println("adaptee specificRequest!");
}
}
public class Adapter extends Adaptee implements Target{
super.specificRequest();
}
}
而对象适配器中Adapter的实现如下:
package org.designpattern.structural.adapterobj;
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void request(){
adaptee.sepcificRequest();
}
}
此外还有一种双向适配器同时实现了源接口(Adaptee)和目标接口(Target),在客户端方可以把双向适配器当做转换后的目标接口使用,而在源系统方可以把双向适配器当做实现了源接口的类使用。这种情况,类适配器天生就是双向适配器(需支持多继承),而对象适配器只实现了Target接口不是双向适配器。
在jdk中io流有使用适配器模式,适配器模式也是其他结构型模式的基础,适配器在设计需要使用遗留系统是时,较常用。