likes
comments
collection
share

设计模式Java实现-适配器模式

作者站长头像
站长
· 阅读数 4

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容: 适配器模式✈️

🍱本篇收录完整代码地址:gitee.com/diqirenge/d…🍱

楔子

从本篇文章开始,小七计划和大家一起学习结构型模式。

结构型模式 (Structural Pattern) 是一种设计模式,主要用于处理类或对象的组合。它的主要目的是描述如何将类或者对象结合在一起形成更大的结构,这就好像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。这些模式都有各自的特点和应用场景。例如:

  • 适配器模式:用于将不同的接口转换成客户希望的另外一个接口,使原本不兼容的接口可以一起工作。
  • 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
  • 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
  • 装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
  • 外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
  • 享元模式:运用共享技术有效地支持大量细粒度的对象。
  • 代理模式:为其他对象提供一种代理以控制对这个对象的访问。

这里我们先从适配器模式讲起。

需求背景

当前我们需要判断一个企业的信用等级,需要从不同的征信系统拉取不同格式的征信数据。假设目前有2个来源,一个是企查查,一个是爱企查,他们提供了以下接口

渠道接口
企查查boolean isLevelOne(String creditCode)
启信宝long queryEnterpriseLevel(String creditCode)

如果就是简单的一个个开发对接,看起来好像是没什么问题,但是对以后代码的拓展和可维护性是有一定影响的,万一后来又接入了其他系统,比如二代征信、蚂蚁信用等等,那又是一堆的if-else。这时,可以使用适配器模式将不同格式的数据统一为相同的格式,以便于后续的存储和使用。

分析设计

1、首先我们抽象出一个统一的接口,上层调这个接口就行了

/**
 * 信用等级是否一级
 *
 * @param creditCode 社会统一信用代码
 * @return boolean
 */
boolean isLevelOne(String creditCode);

2、写2个基于该接口的实现类,分别调用企查查和启信宝,并且进行逻辑判断和组装。

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

设计模式Java实现-适配器模式

模块名称

adapter

模块地址

gitee.com/diqirenge/d…

模块描述

适配器模式代码示例

代码实现

1、先罗列一下外部接口

企查查外部接口

/**
 * 适配器模式 - 企查查外部接口
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public class QiChaChaService {

    public boolean isLevelOne(String creditCode) {
        System.out.println();
        System.out.println("[第三方接口]通过企查查查询企业[" + creditCode + "]是否是一级企业");
        return true;
    }

}

企信保外部接口

/**
 * 适配器模式 - 企信保外部接口
 * 只能获取信用等级,不能直接判断是否是一级
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public class QiXinBaoService {

    public long queryEnterpriseLevel(String creditCode) {
        System.out.println();
        System.out.println("[第三方接口]通过启信宝查询[" + creditCode + "]企业信用等级");
        return 1L;
    }

}

2、编写适配接口

/**
 * 适配器模式 - 统一的适配接口
 * 只能获取信用等级,不能直接判断是否是一级
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public interface CreditAdapterService {

    /**
     * 信用等级是否一级
     *
     * @param creditCode 社会统一信用代码
     * @return boolean
     */
    boolean isLevelOne(String creditCode);

}

3、编写实现类

企信保接口实现类

/**
 * 适配器模式 - 企信保接口实现类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public class QiXinBaoServiceImpl implements CreditAdapterService {

    private QiXinBaoService qiXinBaoService = new QiXinBaoService();

    @Override
    public boolean isLevelOne(String creditCode) {
        return qiXinBaoService.queryEnterpriseLevel(creditCode) == 1L;
    }
}

企查查接口实现类

/**
 * 适配器模式 - 企查查接口实现类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public class QiChaChaServiceImpl implements CreditAdapterService {

    private QiChaChaService qiChaChaService = new QiChaChaService();

    @Override
    public boolean isLevelOne(String creditCode) {
        return qiChaChaService.isLevelOne(creditCode);
    }
}

4、编写测试类

/**
 * 测试适配器模式
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/22
 */
public class AdapterTest {

    @Test
    public void testAdapter() {

        QiXinBaoServiceImpl qiXinBaoService = new QiXinBaoServiceImpl();
        System.out.println("判断是否是一级企业,接口适配(启信宝):" + qiXinBaoService.isLevelOne("100000000000000000"));

        QiChaChaServiceImpl qiChaChaService = new QiChaChaServiceImpl();
        System.out.println("判断是否是一级企业,接口适配(企查查):" + qiChaChaService.isLevelOne("100000000000000000"));
    }


}

5、测试结果

[第三方接口]通过启信宝查询[100000000000000000]企业信用等级

判断是否是一级企业,接口适配(启信宝):true

[第三方接口]通过企查查查询企业[100000000000000000]是否是一级企业

判断是否是一级企业,接口适配(企查查):true

实现要点

1、抽象目标接口

例子中为:CreditAdapterService

2、适配器类中维护被适配者成员

例子中为:

QiChaChaServiceImpl中的private QiChaChaService qiChaChaService = new QiChaChaService();

QiXinBaoServiceImpl中的private QiXinBaoService qiXinBaoService = new QiXinBaoService();

总结

其实有许多设计模式我们在工作中已经用到了,只是自己不自知而已。像适配器模式这种,其实不光可以适配接口,还可以适配类,甚至适配对象和属性也不是不可以。总之一句话,实践出真知,还是要多用多练。