主要分为三类:类适配器模式、对象适配器模式、接口适配器模式
工作原理
适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容
从用户的角度看不到被适配者,是解耦的
用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
用户收到反馈结果,感觉只是和目标接口交互
类适配器
例如,现在有一个提供5V电压充电的接口
// 使用5V充电
public interface Charge5V {
void charging();
}
充电宝类实现了该接口
// 充电宝
public class MobilePower implements Charge5V {
@Override
public void charging() {
System.out.println("使用充电宝给手机充电(5V)");
}
}
然后手机可以充电
// 手机
public class Phone {
public void charge(Charge5V c) {
c.charging();
}
public static void main(String[] args) {
Phone phone = new Phone();
MobilePower mobilePower = new MobilePower();
phone.charge(mobilePower);
}
}
现在有一个插座,输出220V电压
// 插座
public class Socket{
public void chargingWith220V() {
System.out.println("使用插座直接充电(220V)");
}
}
插座类也想给手机充电,但是因为接口类型不匹配,不能充电
现在需要一个适配器类:充电器
// 充电器
public class ChargerAdapter extends Socket implements Charge5V {
@Override
public void charging() {
chargingWith220V();
System.out.println("转化为5V");
}
}
然后插座通过充电器给手机充电
// 手机
public class Phone {
public void charge(Charge5V c) {
c.charging();
}
public static void main(String[] args) {
Phone phone = new Phone();
ChargerAdapter chargerAdapter = new ChargerAdapter();
phone.charge(chargerAdapter);
}
}
输出:
使用插座直接充电(220V)
用适配器转换为5V
对象适配器
简介:
- 基本思路和类适配器相同,只是将Adapter类做修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。
- 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系
- 对象适配器模式是适配器模式中常用的一种
- 使用成本更低,更灵活
仍然使用上面手机充电的例子,修改适配器:
// 充电器
public class ChargerAdapter implements Charge5V {
private Socket socket;
public ChargerAdapter(Socket socket) {
this.socket = socket;
}
public void charging() {
socket.chargingWith220V();
System.out.println("转化为5V");
}
}
在Phone调用:
// 手机
public class Phone {
public void charge(Charge5V c) {
c.charging();
}
public static void main(String[] args) {
Phone phone = new Phone();
Socket socket = new Socket();
ChargerAdapter chargerAdapter = new ChargerAdapter(socket);
phone.charge(chargerAdapter);
}
}
接口适配器
简介
- 又称缺省适配器模式
- 当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现,那么该抽象类的子类可有选择的覆盖父类的某些方法来实现需求
- 适用于一个接口不想使用其所有的方法的情况
例如现在有一个接口Interface1
public interface Interface1 {
void m1();
void m2();
void m3();
void m4();
}
现在有一个Client只想使用m1方法
public class Client {
public void solve(Interface1 i1){
i1.m1();
}
}
于是就可以新建一个抽象适配器,让其实现Interface1:
public abstract class ClientAdapter implements Interface1 {
@Override
public void m1() { }
@Override
public void m2() { }
@Override
public void m3() { }
@Override
public void m4() { }
}
现在在使用Client的时候就可以使用ClientAdapter,只需重写方法m1即可
public static void main(String[] args) {
Client client = new Client();
Interface1 interface1 = new ClientAdapter() {
@Override
public void m1() {
System.out.println("ClientAdapter.m1");
}
};
client.solve(interface1);
}