在软件开发中,我们经常会遇到这样的情况:我们需要使用一个现有的类或者接口,但它与我们系统的目标接口不兼容,而我们又不能修改它。这时候,我们该怎么办呢?大多数情况下我们都可以使用适配器模式来解决这个问题,本文将从以下四个方面讲解适配器模式。
适配器模式(Adapter Pattern)是一种结构型设计模式,它可以将一个接口转换成客户端所期待的另一个接口,从而使原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式也称为包装器模式(WrApper Pattern),因为它通过一个包装类(即适配器)来包装不兼容的接口,并提供统一的目标接口。适配器模式可以在运行时根据需要选择不同的适配器来适配不同的被适配者。
对象适配器模式的各角色定义如下。
适配器模式的优点有:
适配器模式的缺点有:
适配器模式适用于以下场景:
举一个生活中常见的实例,我们新买了一台电视机,其电源插头是两相的,不巧的是墙上的插孔却是三相的,这时电视机便无法通电使用,我们以代码来重现这个场景。
public interface TriplePin {
public void electrify(int l, int n, int e);
}
public interface DualPin {
public void electrify(int l, int n);
}
public class TV implements DualPin {
@Override
public void electrify(int l, int n) {
System.out.println("火线通电:" + l + ",零线通电:" + n);
System.out.println("电视开机");
}
}
这也就意味着 TriplePinAdapter 类能帮助我们将 TV 类与三项接口兼容。
public class TriplePinAdapter implements TriplePin {
private DualPin dualPin;
public TriplePinAdapter(DualPin dualPin) {
this.dualPin = dualPin;
}
@Override
public void electrify(int l, int n, int e) {
// 调用被适配设备的两插通电方法,忽略地线参数e
dualPin.electrify(l, n);
}
}
public class Client {
public static void mAIn(String[] args) {
DualPin dualPinDevice = new TV();
TriplePin triplePinDevice = new TriplePinAdapter(dualPinDevice);
triplePinDevice.electrify(1, 0, -1);
}
}
输出结果如下:
火线通电:1,零线通电:0
电视开机
通过利用适配器模式对系统进行扩展后,我们就不必再为解决兼容性问题去暴力修改类接口了,转而通过适配器,以更为优雅、巧妙的方式将两侧“对立”的接口“整合”在一起,顺利化解双方难以调和的矛盾,最终使它们顺利接通。