本篇来介绍适配器模式(Adapter Design Pattern),它可以将两个不兼容的接口变得兼容,而不需改变原有代码。
1,生活中的适配器
生活中有很多常用的适配器,比如接口转换器和电源转换器。
接口转换器可以将两个不匹配的多媒体接口变得匹配;电源转换器可以将两个不匹配的插头和插座变得匹配。
我们可以将适配器的作用抽象成下面的图。下图中的两个系统是不兼容的:
这时可以创建一个适配器:
经过这个适配器,可以将两个不兼容的系统兼容在一起:
适配器的好处在于,它并没有修改原来的系统,而是再创建一个新的组件来达到我们的需求。
2,适配器模式
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
适配器模式可以分为对象适配器和类适配器两种,每种适配器中都有四个重要的组件:
- Client:客户,只认识目标接口。
- Target:目标接口。
- Adapter:适配器。
- Adaptee:被适配者。
适配器将被适配者转换成目标接口,以供客户使用。
对象适配器使用组合的方式,其类图如下:
因为对象适配器使用组合的方式实现,所以,对于 Adaptee 的所有子类,Adapter 都可以进行适配。
类适配器使用多继承的方式,其类图如下:
3,适配器模式举例
下面列举一个对象适配器的例子,来体会一下如何使用适配器模式。
假如,我们有一个汽车类和一个自行车类:
interface BicycleInterface {
void ride();
}
class Bicycle implements BicycleInterface {
public void ride() {
System.out.println("I am riding a bicycle.");
}
}
interface CarInterface {
void drive();
}
class Car implements CarInterface {
public void drive() {
System.out.println("I am driving a car.");
}
}
小明只会骑自行车而不会开汽车:
public class Adapter {
// 小明只会骑自行车
public static void xiaoMing(BicycleInterface b) {
b.ride();
}
public static void main(String[] args) {
Bicycle b = new Bicycle();
Car c = new Car();
xiaoMing(b); // I am riding a bicycle.
// xiaoMing(c); // 类型不匹配,不会开汽车
}
}
为了不改变 xiaoMing
方法,也就是小明不用学会开汽车,也能用骑自行车的方式开汽车,我们构造了一个 CarAdapter
,CarAdapter
继承了 BicycleInterface
接口,如下:
class CarAdapter implements BicycleInterface {
private CarInterface car;
public CarAdapter(CarInterface car) {
this.car = car;
}
public void ride() {
car.drive();
}
}
CarAdapter
可以将 Car
适配成 Bicycle
,这样小明在 CarAdapter
的帮助下也能开汽车了:
CarAdapter ca = new CarAdapter(c); // 将 Car 适配成 Bicycle
xiaoMing(ca); // 小明可以开汽车了
我将完整的代码放在了这里,供大家参考。
4,总结
也许你已经看出来了,其实适配器模式也是一种装饰对象的方式,就像装饰者模式一样。它们不同点是:
- 适配器模式的主要目的是解决接口的不兼容问题。
- 装饰者模式的主要目的是增强原有对象的行为。
所以,这两种模式的设计意图是不同的。
(本节完。)
推荐阅读:
欢迎关注作者公众号,获取更多技术干货。