一、定义与类型:
》定义:将一个类的接口转换成客户期望的另一个接口
将一个类的接口,就是被适配者,另一个接口就是目标类型
》使原本接口不兼容的类可以一起工作。比如手机或者电脑等一些电器的充电转换头。
》类型:结构型
二、适用场景:
》已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)(为了复用现有的一些类或者数据、行为都正确,但是接口不符合)
》不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案。如果是做一个新的系统,不要考虑该设计模式,该模式有些亡羊补牢的感觉。
三、优点:
》能提高类的透明性和复用,现有的类复用但不需要改变。解决了现有类和目标类不匹配的问题;
》目标类和适配器类解耦,提高程序扩展性
》符合开闭原则。扩展时一般只需要扩展适配器类。
四、缺点:
》适配器编写过程需要全面考虑,可能会增加系统的复杂性;
》增加系统代码可读的难度;
五、适配器扩展:
》对象适配器:符合组合复用原则,使用委托机制。
》类适配器:主要使用继承
六、适配器相关设计模式:
》适配器模式和外观模式:
都是对现有类的封装,外观定义了新的接口,适配器模式则是复用了已有的接口,使得已有的接口符合当前需求。
从复用程度来说,外观模式是适配整个子系统,而适配器模式只是针对某个接口或者类。
七、代码实践:
根据上面的分类,分别实践类适配器模式和对象适配器模式:
1、类适配器模式:
如下定义了一个原始的类,不符合使用方式,需要进行适配的现有类,还有一个想要达到的目标接口,和目标接口实现类。
并且定义了一个适配器方法Adapter类,该类类似于一个充电转换器,可以将现有类按照目标方法给出结果。
package com.zxl.design.pattern.structural.adapter.classadapter;
/**
* Created by Administrator on 2019/7/20.
*/
public class Adaptee {
public void adapteeRequest(){
System.out.println("被适配者的方法");
}
}
package com.zxl.design.pattern.structural.adapter.classadapter;
/**
* Created by Administrator on 2019/7/20.
*/
public interface Target {
void request();
}
package com.zxl.design.pattern.structural.adapter.classadapter;
/**
* Created by Administrator on 2019/7/20.
*/
public class ConcreteTarget implements Target {
public void request() {
System.out.println("ConcreteTarget 目标方法");
}
}
package com.zxl.design.pattern.structural.adapter.classadapter;
/**
* Created by Administrator on 2019/7/20.
*/
public class Adapter extends Adaptee implements Target {
public void request() {
super.adapteeRequest();
}
}
package com.zxl.design.pattern.structural.adapter.classadapter;
/**
* Created by Administrator on 2019/7/20.
*/
public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
}
测试结果和UML图如下:
"D:\Program Files\Java\jdk1.8.0_102\bin\java" "-javaagent:D:\InteliijIDea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=63324:D:\InteliijIDea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_102\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\rt.jar;C:\Users\Administrator\Desktop\gson-master\gson-master\DesignMode\target\classes" com.zxl.design.pattern.structural.adapter.classadapter.Test
ConcreteTarget 目标方法
被适配者的方法
2、对象适配器模式: 和上面的类适配器模式的代码差异,目前就是ConcreteTarget类的差异:
其他地方都一样。
附上ConcreateTarget类的代码
package com.zxl.design.pattern.structural.adapter.objadatper;
/**
* Created by Administrator on 2019/7/20.
*/
public class ConcreteTarget implements Target {
public void request() {
System.out.println("ConcreteTarget 目标方法");
}
}
运行结果和上方也是一致
"D:\Program Files\Java\jdk1.8.0_102\bin\java" "-javaagent:D:\InteliijIDea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=63517:D:\InteliijIDea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_102\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_102\jre\lib\rt.jar;C:\Users\Administrator\Desktop\gson-master\gson-master\DesignMode\target\classes" com.zxl.design.pattern.structural.adapter.objadatper.Test
ConcreteTarget 目标方法
被适配者的方法
附上UML图:
可以对别类适配器模式和对象设计模式的UML图,查看差异
左图为类适配器,右图为对象适配器
差异就在于适配器模式类实现的方案不同,一个是继承关系,一个是组合关系。这也是这两者的最大区别。继承和组合关系在选择时,优先选择组合关系,但也考虑实际业务问题。
3、实用场景,手机充电,转换头