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

适配器模式(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)

java 复制代码
public class ExternalUser {
    private String firstName;
    private String lastName;
    private String email;

    // getters and setters
}

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

java 复制代码
public class InternalUser {
    private String fullName;
    private String emailAddress;

    // getters and setters
}

Feign客户端定义(Adaptee接口)

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

适配器(Adapter)

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

java 复制代码
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对象。

java 复制代码
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中做出相应的调整,而不需要修改系统内部的其他部分。这样不仅增加了代码的可维护性,也提高了系统的灵活性和扩展性。

总结

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

相关推荐
小码编匠10 分钟前
WPF 星空效果:创建逼真的宇宙背景
后端·c#·.net
逊嘘11 分钟前
【Java数据结构】LinkedList
java·开发语言·数据结构
总是学不会.12 分钟前
第五篇:前后端如何“扯皮”——HTTP 在开发中的应用
java·网络·网络协议·http·开发
上海运维Q先生17 分钟前
面试题整理14----kube-proxy有什么作用
运维·面试·kubernetes
代码拯救不了世界21 分钟前
若依框架中的上传图片后如何实现回显到页面的
java·图片上传·若依
heirui_Oooo24 分钟前
利用两种方式分别实现单例模式(懒汉式、饿汉式)
java·开发语言
天使day31 分钟前
Maven
java·maven
汇匠源34 分钟前
共享无人系统,从出行到生活全面覆盖
java·生活
开发者每周简报1 小时前
求职市场变化
人工智能·面试·职场和发展
小灰灰要减肥1 小时前
装饰者模式
java