适配器模式的意图在于,使用不同接口的类所提供的服务为客户端提供它所期望的接口。
类适配器
如上图所示,当我们需要适配现有代码时,可能会发现客户端开发人员已经事先考虑到这种情形。开发人员为客户端使用的服务提供了接口。该接口声明了Client类所要调用的requiredMethod方法。在ExistingClass类中,则定义了usefullMethod方法,它是Client类需要的实现。
若要对ExistingClass类进行适配,满足客户端对象的需要,就可以编写一个继承自ExistingClass,并同时实现RequiredInterface接口的类,通过重写requiredMethod方法将客户端的请求委派给usefullMethod方法。
以下通过代码进行说明:
- Client
public class Client {
private RequiredInterface requiredInterface;
public Client(RequiredInterface requiredInterface){
this.requiredInterface = requiredInterface;
}
//该方法为Client真正要完成的工作
public void dosth(){
this.requiredInterface.requiredMethod();
}
}
- Client依赖的接口类
public interface RequiredInterface {
void requiredMethod();
}
- 原有代码
public class ExistingClass {
/**
* 该方法可以实现Client端需要的功能
*/
public void usefullMethod(){
System.out.println("I'm the really usefull method the client need");
}
}
- 适配器
public class NewClass extends ExistingClass implements RequiredInterface {
@Override
public void requiredMethod() {
this.usefullMethod();
}
}
- 测试类
public class App {
public static void main( String[] args ){
//构造适配器
NewClass newClass = new NewClass();
//客户端传入适配器
Client client = new Client(newClass);
client.dosth();
}
}
以上的设计属于类的适配器,通过子类进行适配。在类的适配器中,新的适配器类实现了需要的接口,并继承自现有的类。当你需要适配的一组方法并非呗定义在接口中时,这种方式就不奏效了。
对象适配器
这种方式的适配器使用了委派而非继承。如上所示,NewClass类是适配器的一个例子,该类的实例同时也是RequiredClass类的实例。换言之,NewClass类满足了客户端的需要。NewClass类通过ExistingClass实例对象,可以将ExistingClass类适配为符合客户端的需要。
- Client
public class Client {
private RequiredClass requiredClass;
public Client(RequiredClass requiredClass){
this.requiredClass = requiredClass;
}
//该方法为Client真正要完成的工作
public void dosth(){
this.requiredClass.requiredMethod();
}
}
- RequiredClass
public class RequiredClass {
public void requiredMethod() {
System.out.println("Telling you the truth, " +
"I can not do what you actually want!");
}
}
- 适配器
public class NewClass extends RequiredClass{
private ExistingClass existingClass;
public NewClass(ExistingClass existingClass){
this.existingClass = existingClass;
}
@Override
public void requiredMethod() {
this.existingClass.usefullMethod();
}
}
- 测试类
public class App {
public static void main( String[] args ){
ExistingClass existingClass = new ExistingClass();
//构造适配器
NewClass newClass = new NewClass(existingClass);
//客户端传入适配器
Client client = new Client(newClass);
client.dosth();
}
}
注意区分:类的适配器继承自现有的类,同时实现目标接口;对象适配器继承自目标类,同时引用现有的类;