适配器模式(Adapter),别名:包装器Wrapper,将一个类的接口转换成Client希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
时机:我们经常会碰到的情况是你无法修改你想要使用的类,这些类库是被发现而非被创建的,在这种情况下,我们可以考虑使用适配器模式。适配器中的代码将接受你所拥有的接口,并产生你所需要的接口。适配器模式主要应用与希望复用一些现存的类,但是接口又与复用环境要求不一致的时候。
适配器模式有两种不同的实现形式:类适配器模式(继承实现)和对象适配器模式(组合实现)。
我们先来介绍类适配器模式,
1. 类适配器模式
类适配器模式就是通过继承方式来实现适配,从而调用想要使用的方法。
类图:
可能刚看类图有点懵逼,那么我们就举一个栗子来具体实现以下。
//package com.dlut.designpattern.adapter;
//Client期待的接口
public interface Target{
public void request();
}
//需要进行适配的类
class Adaptee{
public void specRequest(){
System.out.println("特殊调用...");
}
}
class Adapter extends Adaptee implements Target{
public void request() {
super.specRequest();
}
}
测试类:
//package com.dlut.designpattern.adapter;
public class Test {
public static void main(String[] args) {
Target target=new Adapter();
target.request();
}
}
这里我要着重强调一点,也是很多人的疑惑,Target
必须为interface
接口还是可以定义为类?使用Java实现类适配器模式时,Target
必须定义为interface
,原因是Java实现多继承只能是通过定义接口的方式。所以说,这在一定程度上使得适配器模式的使用受到了限制。那么我们如何来克服这种限制呢,那就是我们接下来介绍的对象适配器模式。
2. 对象适配器模式
对象适配器模式是通过组合方式来实现适配的。
类图:
示例:
//package com.dlut.designpattern.adapter;
//Client期待的接口
public class Target{
public void request(){
System.out.println("普通调用...");
}
}
//需要进行适配的类
class Adaptee{
public void specRequest(){
System.out.println("特殊调用...");
}
}
class Adapter extends Target{
private Adaptee adaptee=null;
public Adapter(Adaptee adaptee){
this.adaptee=adaptee;
}
public void request() {
adaptee.specRequest();
}
}
测试类:
//package com.dlut.designpattern.adapter;
public class Test {
public static void main(String[] args) {
Target target=new Adapter(new Adaptee());
target.request();
}
}
在学习适配器模式时,有时候会走入一个怪圈,就是容易想到去适配不同种类型的电压、不同大小的物体之类的示例。然而,在我的理解中,适配器更强调的是“配”,就像它的别名一样,它在更多情况下就是一个包装器,如果我们能理解这种思想,然后回过头来仔细观察代码时,我们就会恍然大悟,原来它是这个样子的。
参考: