【适配器】设计模式:旧系统迁移与第三方库集成的解决方案

本文主要是介绍【适配器】设计模式:旧系统迁移与第三方库集成的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

适配器设计模式是一种结构设计模式,它允许将一个类的接口转换成客户端期望的另一个接口。适配器让那些接口不兼容的类可以一起工作。这种模式在系统集成、插件开发和第三方库集成中尤为重要。

核心组件:

  • 目标接口(ITarget):期望的接口,要转化成的接口定义,客户端将使用这个接口;
  • 适配者(Adaptee):已存在的类,具有不兼容Target定义的接口;
  • 适配器(Adaptor):将适配者Adaptee的接口转换成目标ITarget的接口。

实现方式

类适配器

类适配器基于继承实现

// 目标接口
public interface ITarget {void f1();void f2();void fc();
}
// 适配者
public class Adaptee {public void fa() { //... }public void fb() { //... }public void fc() { //... }
}
//适配器
public class Adaptor extends Adaptee implements ITarget {public void f1() {super.fa();}public void f2() {//...重新实现f2()...}//fc()不需要实现,直接继承自Adaptee,这是跟对象适配器最大的不同点
}

对象适配器

对象适配器基于组合实现

// 目标接口
public interface ITarget {void f1();void f2();void fc();
}
//适配者
public class Adaptee {public void fa() { ... }public void fb() { ... }public void fc() { ... }
}
//适配器
public class Adaptor implements ITarget {private Adaptee adaptee;public Adaptor(Adaptee adaptee) {this.adaptee = adaptee;}public void f1() {adaptee.fa(); //委托给Adaptee}public void f2() {//...重新实现f2()...}public void fc() {adaptee.fc();}
}

方案选择

类适配器和对象适配器在实际工作中该怎么选择呢?有以下两个维度

  • Adaptee接口的个数
  • AdapteeITarget接口的契合程度

1)若Adaptee接口不多,则两种方式都可以;
2)若Adaptee接口很多,且AdapteeITarget接口定义大部分都相同,推荐使用类适配器,因为Adaptor复用父类Adaptee的接口,比起对象适配器的实现方式,Adaptor的代码量要少一些;
3)若Adaptee接口很多,且AdapteeITarget接口定义大部分都不相同,推荐使用对象适配器,因为组合结构相对于继承更加灵活。

应用场景

适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷,属于无奈之举。如果在设计初期,就能协调规避接口不兼容的问题,那么这种模式就没有应用的机会了。
那么在实际开发中,什么情况下会出现接口不兼容呢?

封装有缺陷的接口设计

假如我们依赖的外部系统在接口设计上有缺陷(比如包含大量静态方法),引入之后会影响到我们自身代码的可测试性。为了隔离设计上的缺陷,我们希望对外部系统提供的接口进行二次封装,抽象出更好的接口设计。

//假设这个类来自外部sdk,我们无权修改它的代码
public class CD { public static void staticFunction1() { //... }public void uglyNamingFunction2() { //... }public void tooManyParamsFunction3(int paramA, int paramB, ...) { //... }public void lowPerformanceFunction4() { //... }
}// 使用适配器模式进行重构
// 目标接口
public interface ITarget {void function1();void function2();void fucntion3(ParamsWrapperDefinition paramsWrapper);void function4();//...
}
//适配器
public class CDAdaptor extends CD implements ITarget {public void function1() {super.staticFunction1();}public void function2() {super.uglyNamingFucntion2();}public void function3(ParamsWrapperDefinition paramsWrapper) {super.tooManyParamsFunction3(paramsWrapper.getParamA(), ...);}public void function4() {//...reimplement it...}
}

统一多个类的接口设计

某个功能的实现依赖多个外部系统或者多个类,通过适配器模式,将它们的接口适配为统一的接口定义,然后就可以使用多态特性来复用代码逻辑。

假如系统 A 要对用户输入的文本进行敏感词过滤,为了提高过滤的召回率,引入了多款第三方敏感词过滤系统,依次对用户输入的内容进行过滤,过滤掉尽可能多的敏感词。
但是,每个系统提供的过滤接口都是不同的。意味着我们无法复用一套逻辑来调用各个系统。此时,我们可以使用适配器模式,将所有系统的接口适配为统一的接口定义,这样我们可以复用调用敏感词过滤的代码。

未使用适配器模式
// A敏感词过滤系统提供的接口
public class ASensitiveWordsFilter { //text是原始文本,函数输出用***替换敏感词之后的文本public String filterSexyWords(String text) {// ...}public String filterPoliticalWords(String text) {// ...} 
}
// B敏感词过滤系统提供的接口
public class BSensitiveWordsFilter  { public String filter(String text) {//...}
}
// C敏感词过滤系统提供的接口
public class CSensitiveWordsFilter { public String filter(String text, String mask) {//...}
}// 未使用适配器模式之前的代码:代码的可测试性、扩展性不好
public class RiskManagement {private ASensitiveWordsFilter aFilter = new ASensitiveWordsFilter();private BSensitiveWordsFilter bFilter = new BSensitiveWordsFilter();private CSensitiveWordsFilter cFilter = new CSensitiveWordsFilter();public String filterSensitiveWords(String text) {String maskedText = aFilter.filterSexyWords(text);maskedText = aFilter.filterPoliticalWords(maskedText);maskedText = bFilter.filter(maskedText);maskedText = cFilter.filter(maskedText, "***");return maskedText;}
}
适配器模式改造
// 统一接口定义
public interface ISensitiveWordsFilter { String filter(String text);
}
// A 适配器
public class ASensitiveWordsFilterAdaptor implements ISensitiveWordsFilter {private ASensitiveWordsFilter aFilter;public String filter(String text) {String maskedText = aFilter.filterSexyWords(text);maskedText = aFilter.filterPoliticalWords(maskedText);return maskedText;}
}
// B 适配器
public class BSensitiveWordsFilterAdaptor implements ISensitiveWordsFilter {private BSensitiveWordsFilter bFilter;public String filter(String text) {String maskedText = bFilter.filter(text);return maskedText;}
}
// C 适配器
public class CSensitiveWordsFilterAdaptor implements ISensitiveWordsFilter {private CSensitiveWordsFilter cFilter;public String filter(String text) {String maskedText = cFilter.filter(text,"");return maskedText;}
}// 扩展性更好,更加符合开闭原则,如果添加一个新的敏感词过滤系统,
// 这个类完全不需要改动;而且基于接口而非实现编程,代码的可测试性更好。
public class RiskManagement { private List<ISensitiveWordsFilter> filters = new ArrayList<>();public void addSensitiveWordsFilter(ISensitiveWordsFilter filter) {filters.add(filter);}public String filterSensitiveWords(String text) {String maskedText = text;for (ISensitiveWordsFilter filter : filters) {maskedText = filter.filter(maskedText);}return maskedText;}
}

替换依赖的外部系统

当我们把项目中依赖的一个外部系统替换为另一个外部系统时,利用适配器模式,可以减少对代码的改动。

假设我们有一个外部系统 A 的接口和实现。

public interface IA {void fa();
}public class A implements IA {public void fa() {System.out.println("Implementation of fa in System A");}
}

还有一个使用外部系统 A 的 Demo 类

public class Demo {private IA a;public Demo(IA a) {this.a = a;}public void doSomething() {a.fa();}
}

现在,我们引入外部系统B以及适配器BAdaptor

public class B {public void fb() {System.out.println("Implementation of fb in System B");}
}// B的适配器
public class BAdaptor implements IA {private B b;public BAdaptor(B b) {this.b = b;}public void fa() {// 适配B的fb方法b.fb();}
}

最后,我们可以在Demo中无缝替换AB,而不影响Demo的代码

public class Client {public static void main(String[] args) {// 使用外部系统ADemo demoWithA = new Demo(new A());demoWithA.doSomething();// 替换为外部系统B,借助适配器Demo demoWithB = new Demo(new BAdaptor(new B()));demoWithB.doSomething();}
}

通过引入适配器,我们在替换外部系统时只需修改实例的创建,而不需要修改Demo中的代码。这符合适配器模式的核心思想,实现了对项目代码的最小侵入性。

适配不同格式的数据

Java 中的 Arrays.asList() 也可以看作一种数据适配器,将数组类型的数据转化为集合容器类型。

List<String> stooges = Arrays.asList("A", "B", "C");

总结

适配器设计模式是一种强大的工具,它允许不兼容的接口协同工作。通过创建适配器,我们可以将现有的类集成到新系统中,而无需修改它们的代码。这种模式提高了代码的可重用性和系统的灵活性。

参考资料:
《极客时间-设计模式之美》

这篇关于【适配器】设计模式:旧系统迁移与第三方库集成的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133557

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能