java设计模式——适配器模式
一. 定义与类型
定义:将一个类的接口转换成客户期望的另一个接口,使原本不兼容的类可以一起工作
类型:结构性
二. 使用场景
(1) 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
(2) 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案
三. 优缺点
优点:
(1) 能提高类的透明性和复用,现有的类复用但不需要改变
(2) 目标类和适配器类解耦,提高程序扩展性
(3) 符合开闭原则
缺点:
(1) 适配器编写过程需要全面考虑,可能会增加系统的复杂新
(2) 增加系统代码可读的难度
四. 适配器—扩展
对象适配器:通过组合,优先先择组合
类适配器:通过继承
五. 相关设计模式
适配器模式和外观模式:
(1) 它们都是对现有的类,现存的系统封装。
(2) 适配器是使用已有的接口,让两个或多个已有的接口协同工作,外观模式定义新的接口,在现有系统中提供一个更为方便的访问入口。
(3) 如果非要把外观模式也称之为适配,那它们最大的区别就是适配的力度不同。外观模式是适配整个子系统,所针对的对象力度更大。
六. Coding
类适配器:
替换目标方法的适配的方法
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:01 **/ public class Adaptee { public void AdapteeRequest() { System.out.println("被适配者的方法"); } }
目标接口:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:02 **/ public interface Target { void request(); }
目标方法:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:03 **/ public class ConcreteTarget implements Target { public void request() { System.out.println("ConcreteTarget目标方法"); } }
适配方法:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:03 **/ public class Adapter extends Adaptee implements Target { public void request() { //...可以加上逻辑 super.AdapteeRequest(); //...可以加上逻辑 } }
应用层:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:05 **/ public class Test { public static void main(String[] args) { Target target = new ConcreteTarget(); target.request(); Target adapterTarget = new Adapter(); adapterTarget.request(); } }
结果:
对象适配器:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:07 **/ public class Adaptee { public void AdapteeRequest() { System.out.println("被适配者的方法"); } }
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:02 **/ public interface Target { void request(); }
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:03 **/ public class ConcreteTarget implements Target { public void request() { System.out.println("ConcreteTarget目标方法"); } }
/** * @program: designModel * @description: 通过组合的方式,把具体实现request的方法委托给Adaptee来实现 * @author: YuKai Fan * @create: 2019-02-11 16:03 **/ public class Adapter implements Target { private Adaptee adaptee = new Adaptee(); public void request() { //... adaptee.AdapteeRequest(); //... } }
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:05 **/ public class Test { public static void main(String[] args) { Target target = new ConcreteTarget(); target.request(); Target adapterTarget = new Adapter(); adapterTarget.request(); } }
从上面的代码可以看出,类适配器与对象适配器主要是在适配的过程,类适配器是通过继承,而对象适配器是通过组合。
用一个业务场景来体现对象适配器模式,
adaptee被适配的方法:
/** * @program: designModel * @description: 220v的交流电 * @author: YuKai Fan * @create: 2019-02-11 16:13 **/ public class AC220 { public int outputAC220V() { int output = 220; System.out.println("输出交流电" + output + "V"); return output; } }
目标方法的接口:
/** * @program: designModel * @description: 目标:5v直流电 * @author: YuKai Fan * @create: 2019-02-11 16:16 **/ public interface DC5 { int outputDC5V(); }
适配方法,将220v交流电,适配为5v直流电:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:17 **/ public class PowerAdapter implements DC5 { private AC220 ac220 = new AC220(); public int outputDC5V() { int adapterInput = ac220.outputAC220V(); //变压器... int adapterOutput = adapterInput/44; System.out.println("使用PowerAdapter输入AC:" + adapterInput + "V" + ",输出DC:" + adapterOutput); return adapterOutput; } }
应用层:
/** * @program: designModel * @description: * @author: YuKai Fan * @create: 2019-02-11 16:19 **/ public class Test { public static void main(String[] args) { DC5 dc5 = new PowerAdapter(); dc5.outputDC5V(); } }
结果:
UML类图:
七. 源码分析
jdk中的xmlAdapter
Spring AOP中的AdvisorAdapter的实现方法
Spring-data-jpa中的JpaVendorAdapter的相关实现类
SpringMVC中的HandlerAdapter的相关实现,
SpringMVC的核心控制器DispatcherServlet