第一节
前言
最近看到一个比较火的文案,“我认为,接受高等教育的目的是帮助家乡摆脱贫困,而不是摆脱贫困的家乡,生如蝼蚁当有鸿鹄之志,为天地立心,为生民立命,为往圣继绝学,为万世开太平”。这句话,火遍了全网,其原因是引发了大多数人的共鸣;从小接触的思想就是好好学习,以后找个好工作,摆脱当前的困境,可是帮助那些仍在困境中漂泊的人,岂不是更有意义。感触颇深的我,也想到了自己的作为,在发表文章、总结经验时,我内心的想法是:
我认为,接受高等教育去学习IT技术的目的,不仅仅只能因为碎银几两,更加是为了让我们的生活更加智能化,让这个社会变得更加美好;写文章的目的也不仅仅是为了自己的经验总结,也是帮助那些未接触过此知识的人更加容易的获得新知识,大家齐并进,IT更美好。
前面一周我讲解了创建型设计模式的6种,从简单工厂模式到单例模式,创建型模式的主要用于描述如何创建对象。今天起我开始讲解结构型模式,此类型模式主要讲解如何将类或者对象按照某种布局组成更大的结构。今天开始结构型模式第一节:适配器模式,所谓适配,顾名思义,在当前不兼容新方式的基础上,完成改造,适配新的方式,具体如何,下面详细讲解。
第三节
适配器模式
概念
适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类适配器模式和对象适配器模式两种。
类适配器模式:主要通过类与类与类之间增加泛化关系及对接口增加实现关系完成对新接口的适配。
对象适配器模式:主要通过对象与对象间增加聚合关系完成适配。
适配器模式组成:
1
目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口,即需要适配的接口。
2
适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口,即目前正在使用的业务类。
3
适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者,即扩展后的类。
场景举例
一个朋友前几年一直在使用3.5mm的圆孔插口耳机,自己手机电脑均使用是3.5mm的插口,有一天这位朋友的手机坏了,买了个新的手机,发现新的手机已经是TypeC接口,目前的3.5mm耳机已经不能用了,但是自己的电脑还是3.5mm的耳机,又不想重新买一条,所以这个时候需要进行适配。此时花几块钱买了个3.5mm转TypeC的转换器,手机想用耳机的时候使用转换器加3.5mm耳机,电脑使用耳机的话,只是使用3.5mm耳机即可,这样子就完成了适配。那这个场景下,目标接口就是TypeC接口,是配置类就是原有的3.5mm接口,当3.5mm+TypeC转换器的时候,这条耳机就是适配器类,既不影响之前功能、又支持新的接口,它完成了适配器要完成的任务。
UML图
今天的UML图使用目前项目开发过程中的json请求处理及form表单程序处理的实例,从form转json的方式来进行类适配器和对象适配器的举例。同样会使用json和form互转的方式讲解类对象的双向适配器,双向适配器可以理解上面场景中转接器的升级,既能3.5mm转TypeC也能TypeC转3.5mm。
类适配器模式UML类图
对象适配器模式UML类图
双向适配器
第三节
代码实现
验证类适配器
1.创建目标接口
package com.yang.adaptee;
/**
* @ClassName Target
* @Description 目标接口
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public interface Target {
/**
* 声明的需要处理form表单的请求
*/
public void fromRequest();
}
2.创建适配者(原有类)
package com.yang.adaptee;
/**
* @ClassName Adaptee
* @Description 适配者
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class Adaptee {
/**
* 可处理json的请求
*/
public void jsonRequest(){
System.out.println("我是Json请求处理程序");
}
}
3.创建类对象适配器
package com.yang.adaptee;
/**
* @ClassName ClassAdapterClient
* @Description 类适配器客户端测试
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class ClassAdapterClient {
public static void main(String[] args) {
System.out.println("类对象适配器测试");
//创建类适配器
Target target = new ClassAdapter();
//测试
target.fromRequest();
}
}
4.创建类对象适配器测试客户端
package com.yang.adaptee;
/**
* @ClassName ClassAdapterClient
* @Description 类适配器客户端测试
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class ClassAdapterClient {
public static void main(String[] args) {
System.out.println("类对象适配器测试");
//创建类适配器
Target target = new ClassAdapter();
//测试
target.fromRequest();
}
}
5.测试结果如下,完成了从form到json的转换,完成了适配器的功能
类对象适配器测试
form转换为json
我是Json请求处理程序
验证对象适配器
1.创建对象适配器
package com.yang.adaptee;
/**
* @ClassName ObjectAdapter
* @Description 对象适配器
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class ObjectAdapter implements Target{
//成员对象
private Adaptee adaptee;
//有参数构造,需要指定构造者对象
public ObjectAdapter(Adaptee adaptee){
this.adaptee = adaptee;
}
@Override
public void fromRequest() {
//适配器将form转换为了json
System.out.println("form转换为json");
//使用原有的json处理方式
adaptee.jsonRequest();
}
}
2.创建对象适配器测试类
package com.yang.adaptee;
/**
* @ClassName ObjectAdapterClient
* @Description 对象适配器测试
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class ObjectAdapterClient {
public static void main(String[] args) {
System.out.println("对象适配器测试");
//创建需要的适配者对象
Adaptee adaptee = new Adaptee();
//创建对象适配器
Target target = new ObjectAdapter(adaptee);
//测试
target.fromRequest();
}
}
3.运行结果如下,同样完成了适配
对象适配器测试
form转换为json
我是Json请求处理程序
验证双向适配器
1.创建Json适配者
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName AdapteeJson
* @Description Json适配者
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class AdapteeJson {
/**
* 可处理json的请求
*/
public void jsonRequest(){
System.out.println("我是Json请求处理程序");
}
}
2.创建form适配者
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName AdapteeForm
* @Description form适配者
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class AdapteeForm {
/**
* 可处理from的请求
*/
public void formRequest(){
System.out.println("我是form请求处理程序");
}
}
3.创建json的目标接口
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName TargetJson
* @Description 注释
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public interface TargetJson {
//抽象json处理方法声明
public void jsonRequest();
}
4.创建form的目标接口
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName Targetform
* @Description 注释
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public interface Targetform {
//声明抽象的form请求
public void formRequest();
}
5.创建双向适配器
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName TwoWayAdapter
* @Description 双向适配器
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class TwoWayAdapter implements Targetform,TargetJson{
//成员对象
private AdapteeForm adapteeForm;
private AdapteeJson adapteeJson;
//form有参构造
public TwoWayAdapter(AdapteeForm adapteeForm){
this.adapteeForm = adapteeForm;
}
//json有参构造
public TwoWayAdapter(AdapteeJson adapteeJson){
this.adapteeJson = adapteeJson;
}
@Override
public void jsonRequest() {
System.out.println("json转from");
adapteeForm.formRequest();
}
@Override
public void formRequest() {
System.out.println("fom转json");
adapteeJson.jsonRequest();
}
}
6.创建双向适配器测试客户端
package com.yang.adaptee.TwoWayAdapter;
/**
* @ClassName TwoWayAdapterClient
* @Description 双向适配器测试
* @Author IT小白架构师之路
* @Date 2020/12/16
* @Version 1.0
**/
public class TwoWayAdapterClient {
public static void main(String[] args) {
System.out.println("测试json转form适配者");
//创建适配者
AdapteeForm adapteeForm = new AdapteeForm();
//创建适配器
TargetJson targetJson = new TwoWayAdapter(adapteeForm);
targetJson.jsonRequest();
System.out.println("---------------我是分割线----------------");
System.out.println("测试form转json适配者");
//创建适配者
AdapteeJson adapteeJson = new AdapteeJson();
//创建适配器
Targetform targetform = new TwoWayAdapter(adapteeJson);
targetform.formRequest();
}
}
7.测试结果如下,完成了json到form、form到json的双向互转。
测试json转form适配者
json转from
我是form请求处理程序
---------------我是分割线----------------
测试form转json适配者
fom转json
我是Json请求处理程序
第四节
适配器模式优缺点及适用场景
优点:
1.客户端通过适配器可以透明地调用目标接口,需要提前知道目标适配者是谁。
2.可以将现有的类进行复用,完成新功能的支持,不需要修改原有代码。
3.将目标类与适配者类进行了解耦,解决了目标类和适配者类接口不一致的问题。
缺点:
1.增加适配器时需要考虑业务场景需要的适配者,会增加系统的复杂性。
2.代码阅读起来会难一点,对开发人员不友好,增加维护难度。
类适配器缺点
需要增加新的适配器时只能重新编写适配器,因为Java只支持单继承。
对象适配器缺点:
对象适配器会造成适配器成员对象变多,增加了复杂性。
适用场景:
1. 三方对接时,目前已经存在的类的接口与新接入的接口规范不能对照,需要创建一个新的适配器去处理。
2. 将系统中已有类的方法进行整合复用时。
3. 多方对接时,需要多方进行接口兼容时,可考虑多向适配器。