适配器模式在微服务的巧妙应用

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间可以一起工作。适配器模式通常用于将一个类的接口转换成客户端期望的另一种接口,从而使原本因接口不兼容而不能一起工作的类可以一起工作。

适配器模式的介绍

适配器模式主要涉及三个角色:

  1. 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。

  2. 待适配的类(Adaptee):需要被适配的类或接口。

  3. 适配器(Adapter):通过包装一个需要被适配的对象,把原接口转换成目标接口。

适配器模式有两种实现方式:

  • 类适配器模式:通过继承来实现适配器功能。

  • 对象适配器模式:通过组合来实现适配器功能。

优缺点

优点

  1. 提高了类的复用性:系统的需求变化时,不需要修改原有的代码,只需要添加适配器即可重用现有的功能。

  2. 增加了类的透明性和灵活性:客户端代码可以透明地调用目标接口。

  3. 灵活性和扩展性都非常好:如果需要改变适配逻辑,只需更换具体的适配器即可。

缺点

  1. 过多地使用适配器会使系统凌乱。例如,明明看到调用的是A接口,实际上内部被适配成了B接口的实现。

  2. 由于Java至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是接口。

在Spring Cloud中通过Feign使用适配器模式

在Spring Cloud中,Feign是一个声明式的Web服务客户端,它使得编写Web服务客户端变得更加简单。我们可以通过Feign来调用外部接口。当外部接口的参数与我们的系统不兼容时,可以使用适配器模式来进行适配。

假设我们有一个外部微服务,它提供了一个接口,用于获取用户信息,但是这个接口的用户信息对象的结构与我们的系统中使用的用户信息对象的结构不一致。

外部服务的用户信息对象(Adaptee)

public class ExternalUser {
    private String firstName;
    private String lastName;
    private String email;

    // getters and setters
}

我们系统中的用户信息对象(Target)

public class InternalUser {
    private String fullName;
    private String emailAddress;

    // getters and setters
}

Feign客户端定义(Adaptee接口)

@FeignClient(name = "external-user-service")
public interface ExternalUserService {
    @GetMapping("/user/{id}")
    ExternalUser getUserById(@PathVariable("id") String userId);
}

适配器(Adapter)

我们创建一个适配器,它实现我们系统中定义的接口,并在内部调用Feign客户端,将ExternalUser转换为InternalUser

public class UserAdapter implements UserService {

    private final ExternalUserService externalUserService;

    public UserAdapter(ExternalUserService externalUserService) {
        this.externalUserService = externalUserService;
    }

    @Override
    public InternalUser getUserById(String userId) {
        ExternalUser externalUser = externalUserService.getUserById(userId);
        return new InternalUser(externalUser.getFirstName() + " " + externalUser.getLastName(),
                                externalUser.getEmail());
    }
}

使用适配器

现在,当我们的系统需要获取用户信息时,我们可以通过UserAdapter来获取,它会在内部调用外部服务,并将获取到的ExternalUser对象转换为我们系统中的InternalUser对象。

public class UserServiceClient {

    private final UserService userService;

    public UserServiceClient(UserService userService) {
        this.userService = userService;
    }

    public InternalUser getUserById(String userId) {
        return userService.getUserById(userId);
    }
}

下面是对象之间的关系:

图片

在这个例子中,UserAdapter充当了适配器的角色,它把外部服务返回的ExternalUser对象转换为我们系统内部使用的InternalUser对象。这样,即使外部服务的接口或数据结构发生变化,我们也只需要在UserAdapter中做出相应的调整,而不需要修改系统内部的其他部分。这样不仅增加了代码的可维护性,也提高了系统的灵活性和扩展性。

总结

通过适配器方式,我们可以将不兼容的接口或数据模型转换为我们的系统可以使用的形式,同时保持系统的整洁和一致性。这样做还有助于隔离系统与外部服务的直接依赖,当外部服务变化时,只需修改适配器逻辑,而不会影响到系统的其他部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/424739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图书管理系统(使用IO流实现数据的读取和写入)--version4.0

目录 一、项目要求: 二、项目环境 三、项目使用的知识点 四、项目代码 五、项目运行结果 六、项目难点分析 图书管理系统--versions1.0: 图书管理系统--versions1.0-CSDN博客文章浏览阅读981次,点赞29次,收藏17次。本文使用…

代码随想录算法训练营第四十天|139.单词拆分,多重背包介绍,背包问题总结篇!

系列文章目录 代码随想录算法训练营第一天|数组理论基础,704. 二分查找,27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

创建型模式之原型模式

一、概述 1、工作原理:将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程 2、通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,每一个克隆对象都是独立的 3…

虚拟线程目前不推荐上生产的个人思考

1. pin 线程引发的问题比预期严重,需要修改的库繁多 截止目前 Java 21 虚拟线程一些比较严重的 Bug: 1. Thread.HoldsLock(Object) 这个方法,如果是虚拟线程调用,会在平台线程获取到锁之后,就算切换虚拟线程&#xf…

JavaScript闭包漏洞与修补措施

请先看下面一段代码 var obj (function () {var sonObj {a: 1,b: 2}return {get: function (v) {return sonObj[v]}}})()可以看出,这是一段很典型的js闭包代码,可以通过obj调用get方法传一个参数,如果传的是a就可以得到闭包内的对象sonObj.a var obj (function () {var sonO…

2024真正有效的苹果mac电脑清理工具CleanMyMac X

一、前言 对于Mac用户来说,电脑卡顿、运行缓慢无疑是一件令人头疼的事情。而市面上的清理软件又五花八门,效果参差不齐,如何才能找到一款真正有效的清理工具呢?今天,我们为大家推荐一款实力派电脑清理软件——CleanMy…

Canvs的js库:Fabric.js简单强大,用于绘制各种图形

Fabric.js是一个用于创建交互式的HTML5 Canvas应用程序的JavaScript库。它提供了一个简单而强大的API,用于在Web浏览器中绘制和操作图形对象。Fabric.js可以用于创建各种图形应用程序,例如绘图编辑器、图像编辑器、流程图、地图和数据可视化等。 官网文…

图像物体的边界- 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C 题目描述 给定一个二维数组M行N列,二维数组里的数字代表图片的像素,为了简化问题,仅包含像素1和5两种像素,每种像素代表一个…

C语言中的字符魔法:大小写转换的艺术

引言 在C语言的世界里,字符处理是一项基础且重要的任务。字符作为编程中最基本的元素之一,承担着信息展示、数据交互等多重角色。特别是在处理文本信息时,字符的转换和识别显得尤为重要。大小写字母的转换就是其中一个常见的需求&#xff0c…

STM32作为SPI slave与主机异步通信

背景 最近被测试提了个BUG,说某款产品在用户按下前面板的按键后,对应的按键灯没有亮起来。前面板跟主机是通过SPI口通信,前面板是从机,从机想要主动发送消息,需要通过GPIO中断来通知主机: 上图前面板是ST…

flurl升级之后没有FlurlNewtonsoftJsonSerializer

新建NewtonsoftJsonSerializer.cs /// <summary> /// ISerializer implementation based on Newtonsoft.Json. /// Default serializer used in calls to GetJsonAsync, PostJsonAsync, etc. /// </summary> public class NewtonsoftJsonSerializer : IJsonSerial…

【CSP试题回顾】202312-1-仓库规划

CSP-202312-1-仓库规划 解题思路 定义结构体和变量&#xff1a; 结构体 MyWareHouse&#xff0c;用来存储每个仓库的索引&#xff08;编号&#xff09;和位置编码。定义了整数 n 和 m&#xff0c;分别代表仓库的数量和位置编码的维数。定义了一个 vector<MyWareHouse> 的…

图解Vivado工程的目录结构

一、目录结构 ​在使用Vivado进行工程设计时&#xff0c;创建工程以及运行工程的过程中都会生成大量的目录和文件&#xff0c;下面图将对目录和文件结构及功能进行一个简单说明。 工程示例图 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 二、参考资料…

ShardingJdbc分库分表-浅谈分表原理

文章目录 为什么要分库分表一、分库分表二、不停机分库分表数据迁移 为什么要分库分表 一般的机器&#xff08;4核16G&#xff09;&#xff0c;单库的MySQL并发&#xff08;QPSTPS&#xff09;超过了2k&#xff0c;系统基本就完蛋了。最好是并发量控制在1k左右。这里就引出一个…

kubesphere jenkins 流水线 未运行(解决方案)

场景&#xff1a; 在kubesphere 中运行 流水线 devops 结果&#xff0c;显示未运行 但是用 admin 账户是可以运行成功的。 问题解决 1- 查日志&#xff1a; 然后 Caused: org.acegisecurity.userdetails.UsernameNotFoundException: org.springframework.security.core.…

JVM运行时数据区——运行时数据区及线程概述

文章目录 1、运行时数据区概述2、线程3、小结 内存是非常重要的系统资源&#xff0c;是硬盘和CPU的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM在程序执行期间把它所管理的内存分为若干个不同的数据区域。这些不同的数据区域可以分为两种类型&#xff…

吴恩达机器学习全课程笔记第六篇

目录 前言 P96-P100 使用多个决策树 随机森林算法 XGBoost 什么时候使用决策树 P101-P107 聚类 K-means 初始化K-means 选择聚类的个数 P108-P113 异常检测算法 开发和评估异常检测系统 异常检测vs监督学习 选择要使用的特征 前言 这是吴恩达机器学习笔记的第…

【嵌入式实践】【芝麻】【设计篇-2】从0到1给电动车添加指纹锁:项目可行性分析

0. 前言 该项目是基于stm32F103和指纹模块做了一个通过指纹锁控制电动车的小工具。支持添加指纹、删除指纹&#xff0c;电动车进入P档等待时计时&#xff0c;计时超过5min则自动锁车&#xff0c;计时过程中按刹车可中断P档状态&#xff0c;同时中断锁车计时。改项目我称之为“芝…

基于反光柱特征的激光定位算法思路

目录 1. 识别反光柱2. 数据关联2.1 基于几何形状寻找匹配2.2 暴力寻找匹配 3. 位姿估计&#xff08;最小二乘求解&#xff09;4. 问题4.1 精度问题4.2 快速旋转时定位较差 1. 识别反光柱 反光柱是特殊材料制成&#xff0c;根据激光雷达对反光材料扫描得到的反射值来提取特征。…

如何解决微服务的数据一致性分发问题?

介绍 系统架构微服务化以后,根据微服务独立数据源的思想,每个微服务一般具有各自独立的数据源,但是不同微服务之间难免需要通过数据分发来共享一些数据,这个就是微服务的数据分发问题。Netflix/Airbnb等一线互联网公司的实践[参考附录1/2/3]表明,数据一致性分发能力,是构…