一、是什么?
定义: 将一个类的接口变成另外一个类所期待的另一个接口, 从而使因接口不匹配而无法一起工作的两个类能够一起工作
举个例子, 苹果手机想用type-c的充电器充电, 但充电接口不吻合, 所以就选哦一个转接头, 使type-c
能给苹果手机充电, 这就是适配器
二、适配器的三种实现
2.1 接口适配器模式
SpringMvc中因为handler有三种实现方式(implements Controller、implements HttpRequestHandler、@RequestMapping),要执行这三种handler的话,需要对应适配器才行。这就是接口适配器模式的实际应用之一。
下面的例子用type-c充任何电器
2.1.1类图
2.1.2 代码实现
注:support方法判断当前适配器是否适配这个数码电器
// 被适配的数码电器接口
public interface DigitalAppliance {void charge();
}// 耳机
public class Earphone implements DigitalAppliance{@Overridepublic void charge() { System.out.println("earphone charge...");}
}// 手机
public class Phone implements DigitalAppliance{@Overridepublic void charge() { System.out.println("phone charge...");}
}// Mp3
public class Mp3 implements DigitalAppliance{@Overridepublic void charge() { System.out.println("mp3 charge...");}
}// 期望的接口
public interface ChargeAdapter {void charge(DigitalAppliance digitalAppliance);boolean support(DigitalAppliance digitalAppliance);
}// 耳机充电适配器
public class EarphoneChargeAdapter implements ChargeAdapter{@Overridepublic void charge(DigitalAppliance digitalAppliance) {System.out.println("转为Earphone充电...");digitalAppliance.charge();}@Overridepublic boolean support(DigitalAppliance digitalAppliance) {return digitalAppliance instanceof Earphone;}
}// 手机充电适配器
public class PhoneChargeAdapter implements ChargeAdapter{@Overridepublic void charge(DigitalAppliance digitalAppliance) {System.out.println("转为phone充电...");digitalAppliance.charge();}@Overridepublic boolean support(DigitalAppliance digitalAppliance) {return digitalAppliance instanceof Phone;}
}// Mp3充电适配器
public class Mp3ChargeAdapter implements ChargeAdapter{@Overridepublic void charge(DigitalAppliance digitalAppliance) {System.out.println("转为mp3充电...");digitalAppliance.charge();}@Overridepublic boolean support(DigitalAppliance digitalAppliance) {return digitalAppliance instanceof Mp3;}
}public class Typec {private static final List<ChargeAdapter> CHARGE_ADAPTERS = new ArrayList<>();static {// 获取所有的适配器CHARGE_ADAPTERS.add(new PhoneChargeAdapter());CHARGE_ADAPTERS.add(new EarphoneChargeAdapter());CHARGE_ADAPTERS.add(new Mp3ChargeAdapter());}public static void main(String[] args) {DigitalAppliance digitalAppliance = new Phone();// 获取合适的适配器ChargeAdapter chargeAdapter = getChargeAdapter(digitalAppliance);chargeAdapter.charge(digitalAppliance);}private static ChargeAdapter getChargeAdapter(DigitalAppliance digitalAppliance) {for (ChargeAdapter chargeAdapter : CHARGE_ADAPTERS) {// 判断是否适配if (chargeAdapter.support(digitalAppliance)) {return chargeAdapter;}}throw new RuntimeException("没有合适的适配器");}
}
2.2 类适配器模式
Iphone所期待的充电插口可以是接口也可以是抽象类或具体类。被适配类和适配器是父子关系,适配器作为能充苹果的Typec
2.2.1 类图
2.2.2 代码实现
// 被适配的类
public class TypeC {public void charge() {System.out.println("type-c充电....");}
}// 期望使用的接口
public interface IphoneChargeAdapter {void chargeToIphone();
}// 适配器,继承Typec,把自己当成Typec,但又可以充苹果
public class TypeCToIphoneAdapter extends TypeC implements IphoneChargeAdapter {@Overridepublic void chargeToIphone() {System.out.println("转换成iphone口....");charge();}public static void main(String[] args) {// 使用IphoneChargeAdapter iphoneChargeAdapter = new TypeCToIphoneAdapter();iphoneChargeAdapter.chargeToIphone();}
}
2.3 对象适配器模式
被适配类和适配器是组合关系,作为适配器的属性存在。
2.3.1 类图
2.3.2 代码实现
public interface IphoneChargeAdapter {void chargeToIphone();
}public class TypeC {public void charge() {System.out.println("type-c充电....");}
}public class TypeCToIphoneAdapter implements IphoneChargeAdapter {TypeC typeC;public TypeCToIphoneAdapter(TypeC typeC) {this.typeC = typeC;}@Overridepublic void chargeToIphone() {System.out.println("转换成iphone口....");typeC.charge();}public static void main(String[] args) {TypeC typeC = new TypeC();IphoneChargeAdapter adapter = new TypeCToIphoneAdapter(typeC);adapter.chargeToIphone();}}
五、与装饰器模式的区别
装饰器模式的目的是在原有功能的基础之上增强扩展功能。而适配器模式的目的是将一个接口转变成另一个接口,改变原有接口的功能。
六、优点
- 提高了类的复用,低耦合
- 灵活性好,不想用适配器,直接删除就好,不会影响
- 较好的扩展性,符合开闭原则
原文: Java设计模式之适配器模式_吖土豆的博客-CSDN博客