适配器模式(Adapter Pattern): 将某个类的接口转换成客户端期望的另一个接口表示, 主要目的是兼容性, 让原来不兼容的两个接口协同工作, 其别名为包装器(Wrapper).
适配器模式属于结构型模式, 主要分为三类:
适配器模式的工作原理
类适配器模式(Class Adapter Pattern): Adapter适配器类, 继承 Adaptee被适配器类, 实现 Target目标类的接口, 完成适配.
举例: 在生活中手机充电器, 需要将家用220V的交流电 转换为 5V的直流电后, 才能对手机充电. 在这个案例中
Adaptee被适配器类: 220V电压类
class Voltage220VAdaptee {
public int output220V() {
System.out.println("家用输出220V电压");
return 220;
}
}
Target目标接口: 输出5V电压的抽象方法
interface Voltage5VTarget {
int output5V();
}
Adapter适配器类: 将220V电压 转换成 5V电压
class VoltageAdapter extends Voltage220VAdaptee implements Voltage5VTarget {
@Override
public int output5V() {
int v = super.output220V();
v = v / 44;
System.out.println("VoltageAdapter适配类: 将220V电压 转换成 5V电压");
return v;
}
}
手机实体类
class Phone {
public void charge(Voltage5VTarget voltage5VTarget) {
System.out.println("手机充电压为: " + voltage5VTarget.output5V() + "V");
}
}
测试:
public class ClassAdapterPattern {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charge(new VoltageAdapter());
}
}
对象适配器模式(Object Adapter Pattern): 基本思路与类适配器模式相同, 只是将 Adapter适配器类修改, 不是继承 Adaptee被适配者, 而是拥有 Adaptee类的实例, 以解决兼容性的问题.
根据 “合成复用原则”, 在系统中尽量使用关联关系来替代继承关系.
修改VoltageAdapter适配器类, 将继承 Voltage220VAdaptee类, 修改成拥有 Voltage220VAdaptee类的成员属性
class VoltageAdapter implements Voltage5VTarget {
private Voltage220VAdaptee voltage220VAdaptee;
public VoltageAdapter(Voltage220VAdaptee voltage220VAdaptee) {
this.voltage220VAdaptee = voltage220VAdaptee;
}
@Override
public int output5V() {
int v = voltage220VAdaptee.output220V();
v = v / 44;
System.out.println("VoltageAdapter适配类: 将220V电压 转换成 5V电压");
return v;
}
}
...
public class ObjectAdapterPattern {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charge(new VoltageAdapter(new Voltage220VAdaptee()));
}
}
对象适配器模式, 根据合成复用原则, 使用组合替代继承, 解决了类适配器必须继承 Adaptee被适配者, 同时也不在要求 Target目标必须是接口, 可以为抽象类
接口适配器模式(Default Adapter Pattren): 又称之为 缺省适配器模式. 当不需要实现接口提供的所有方法时, 可先设计一个抽象类(AbsAdapter)实现接口, 并为该接口中每个方法提供一个默认实现(空方法). 那么使用抽象类AbsAdapter时, 可有选择地覆盖父类的默写方法来实现需求. 适用于一个接口不想使用其所有的方法的情况
Interface1接口: 只想使用method1方法
interface Interface1 {
void method1();
void method2();
void method3();
void method4();
}
AbsAdapter 抽象类实现接口, 并为该接口中每个方法提供一个默认实现(空方法)
abstract class AbsAdapter implements Interface1 {
// 默认实现, 空方法
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
}
测试: 通过匿名函数使用抽象类AbsAdapter, 覆盖重写method1方法
public class DefaultAdapterPattern {
public static void main(String[] args) {
AbsAdapter absAdapter = new AbsAdapter() {
@Override
public void method1() {
System.out.println("只是用method1方法");
}
};
absAdapter.method1();
}
}