适配器模式
自理解:
将给予的数据通过
适配类
进行中转修改达到数据适应需求的数据类型或值等;结构性模式
定义
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
三种适配器
类的适配器模式、对象的适配器模式、接口的适配器模式
作用
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。
类分布
Adaptee
:适配的类,它是需要被访问的、需要被适配的组件
Target
:当前接口,当前系统业务所使用的接口,可以是抽象类或接口
Adapter
:适配器,通过继承和实现目标接口,让客户端按照目标接口的方法访问适配者
Client
:(响应端)客户端,适配器的使用者类适配器模式
类适配器模式优缺点
优点:由于Adapter继承了Adaptee类,所以它可以根据需求重写Adaptee类的方法,使得Adapter的灵活性增强了。
缺点:因为java单继承的缘故,Target类
必须是接口
,以便于Adapter去继承Adaptee并实现Target,完成适配的功能,但这样就导致了Adapter里暴露了Adaptee类的方法,使用起来的成本就增加了。实例:::
/** * 适配的类(Adaptee):现在需要适配的接口。 */ public class AC220 { /** * 输出220V交流电 * * @return */ public int output220V() { int output = 220; return output; } } /** * 当前接口(Target):这就是所期待得到的接口。 * 注意:由于这里讨论的是类适配器模式,因此目标不可以是类。 */ public interface DC5 { /** * 输出5V直流电(期待得到的接口) * * @return */ int output5V(); } /** * 适配器 * 适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。 */ public class PowerAdapter extends AC220 implements DC5 { /** * 输出5V直流电 * * @return */ @Override public int output5V() { int output = output220V(); return (output / 44); } } /** * 测试类响应 */ public class TestClassAdapter { public static void main(String[] args) { DC5 dc5 = new PowerAdapter(); System.out.println("输出电流:" + dc5.output5V() + "V"); } }对象适配器模式
对象适配器模式优缺点
优点:根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承Adaptee的局限性问题,也不再要求Target必须是接口。使用成本更低,更灵活。
实例:::
/** * 适配的类(Adaptee):现在需要适配的接口。 */ public class AC220 { /** * 输出220V交流电 * * @return */ public int output220V() { int output = 220; return output; } } /** * 当前接口(Target):这就是所期待得到的接口。 */ public interface DC5 { /** * 输出5V直流电(期待得到的接口) * * @return */ int output5V(); } /** * 适配器 */ public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } /** * 输出5V直流电 * * @return */ @Override public int output5V() { int output = this.ac220.output220V(); return (output / 44); } } /** * 测试响应 */ public class TestObjectAdapter { public static void main(String[] args) { AC220 ac220 = new AC220(); PowerAdapter powerAdapter = new PowerAdapter(ac220); System.out.println("输出电流:" + powerAdapter.output5V() + "V"); } }接口适配器
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
/** * 适配的类(Adaptee):现在需要适配的接口。 */ public interface BritishStandard { String getBritishStandard(); String getTypeC(); String getUSB(); } /** * 适配器 */ @AllArgsConstructor public abstract class StandardAdapter extends ChineseStandard implements BritishStandard { @Override public String getBritishStandard() { return null; } @Override public String getTypeC() { return null; } @Override public String getUSB() { return null; } } /** * 测试类 */ public class AdapterTest { public static void main(String[] args) { StandardAdapter standardAdapter= new StandardAdapter() { @Override public String getBritishStandard() { return new ChineseStandard().getChineseStandard(); } }; // 充电成功! new Notebook().charge(standardAdapter); } }