Java 设计模式之适配器模式:系统集成的万能接口

目录

1.模式概述

适配器模式(Adapter Pattern)是一种结构型设计模式 ,其核心使命是解决接口不兼容问题。它如同现实世界中的电源转换器,让不同标准的设备能够协同工作:
调用 适配器实现 转换调用 客户端 Client 目标接口 Target 适配器 Adapter 被适配者 Adaptee

在软件领域体现为:

  • 接口转换:将不兼容接口转换为目标接口
  • 复用兼容:使已有类能被新系统复用
  • 解耦隔离:避免直接修改已有代码
  • 透明集成:客户端无感知使用不同接口

💡 当系统演进遇到接口冲突时,适配器是比强制修改更优雅的解决方案

2.模式结构解析

2.1 UML类图详解

包含 使用 <<interface>> Target +request() : void Adaptee +specificRequest() : void Adapter -adaptee: Adaptee +request() : void Client +execute(Target)

2.2 核心角色职责

角色 职责 设计原则体现
Target(目标) 客户端期望的接口 接口隔离原则
Adaptee(源) 需要被适配的现有接口 开闭原则
Adapter(适配器) 接口转换的实现者 单一职责原则
Client(客户端) 使用目标接口的组件 依赖倒置原则

3.两种实现范式

3.1 UML类图对比

ObjectAdapter -adaptee: Adaptee +request() ClassAdapter +request() <<interface>> Target +request() Adaptee +specificRequest()

3.2 对象适配器 vs 类适配器

特性 对象适配器 类适配器
实现方式 组合 继承
灵活性 可适配多个Adaptee 仅适配一个Adaptee
子类化 不继承Adaptee 继承Adaptee
Java支持 完全支持 伪多重继承
推荐度 ★★★★★ ★★☆☆☆

3.3 代码实现对比

3.3.1 对象适配器(推荐方式)

java 复制代码
// 目标接口
interface USB {
    void connect();
}

// 被适配者
class TypeC {
    public void typeCConnect() {
        System.out.println("Type-C connected");
    }
}

// 对象适配器
class TypeCToUSBAdapter implements USB {
    private TypeC typeC;
    
    public TypeCToUSBAdapter(TypeC typeC) {
        this.typeC = typeC;
    }
    
    @Override
    public void connect() {
        typeC.typeCConnect();
    }
}

3.3.2 类适配器(Java中通过继承实现)

java 复制代码
// 类适配器
class TypeCClassAdapter extends TypeC implements USB {
    @Override
    public void connect() {
        super.typeCConnect(); // 通过继承调用
    }
}

4.适配器模式变体

4.1 双向适配器

java 复制代码
class BidirectionalAdapter implements ModernLogger, LegacyLoggerInterface {
    private ModernLogger modernLogger;
    private LegacyLogger legacyLogger;
    
    // 支持双向转换
    public void modernToLegacy(ModernLogger logger) {
        this.modernLogger = logger;
    }
    
    public void legacyToModern(LegacyLogger logger) {
        this.legacyLogger = logger;
    }
    
    @Override
    public void log(String message, String level) {
        // 调用LegacyLogger的实现...
    }
    
    @Override
    public void log(String message) {
        // 调用ModernLogger的实现...
    }
}

4.2 参数适配器

java 复制代码
class PaymentProcessor {
    // 原始方法
    void processPayment(double amount, String currency, String account) {
        // ...
    }
}

// 参数适配器
class UnifiedPaymentAdapter {
    private PaymentProcessor processor = new PaymentProcessor();
    
    void process(PaymentRequest request) {
        processor.processPayment(
            request.getAmount(), 
            request.getCurrency().name(),
            request.getAccountNumber()
        );
    }
}

// 统一参数对象
record PaymentRequest(double amount, Currency currency, String accountNumber) {}

5.应用场景深度探索

5.1 遗留系统集成

java 复制代码
// 旧版订单系统
class LegacyOrderSystem {
    public void createOrder(String customerName, List<String> items) {
        System.out.println("Legacy order created for " + customerName);
    }
}

// 新版订单接口
interface ModernOrderSystem {
    void placeOrder(Order order);
}

// 适配器实现
class OrderSystemAdapter implements ModernOrderSystem {
    private LegacyOrderSystem legacySystem;
    
    public OrderSystemAdapter(LegacyOrderSystem system) {
        this.legacySystem = system;
    }
    
    @Override
    public void placeOrder(Order order) {
        // 转换参数格式
        List<String> legacyItems = order.getItems().stream()
            .map(Item::getCode)
            .collect(Collectors.toList());
        
        legacySystem.createOrder(order.getCustomer().getName(), legacyItems);
    }
}

5.2 跨平台UI组件适配

java 复制代码
// 安卓组件
class AndroidButton {
    public void draw() { /* Android渲染逻辑 */ }
    public void setOnTouchListener(Runnable action) { ... }
}

// iOS组件
class IOSButton {
    public void render() { /* iOS渲染逻辑 */ }
    public void addTapHandler(Runnable handler) { ... }
}

// 统一UI接口
interface CrossPlatformButton {
    void display();
    void onClick(Runnable action);
}

// 安卓适配器
class AndroidButtonAdapter implements CrossPlatformButton {
    private AndroidButton button = new AndroidButton();
    
    @Override
    public void display() {
        button.draw();
    }
    
    @Override
    public void onClick(Runnable action) {
        button.setOnTouchListener(action);
    }
}

// iOS适配器
class IOSButtonAdapter implements CrossPlatformButton {
    private IOSButton button = new IOSButton();
    
    @Override
    public void display() {
        button.render();
    }
    
    @Override
    public void onClick(Runnable action) {
        button.addTapHandler(action);
    }
}

5.3 微服务协议转换

java 复制代码
// REST服务接口
interface RestService {
    User getUser(String id);
}

// gRPC服务客户端
class GrpcUserService {
    public UserProto getUser(UserRequest request) {
        // gRPC调用实现
    }
}

// gRPC-REST适配器
class GrpcToRestAdapter implements RestService {
    private GrpcUserService grpcService;
    
    public GrpcToRestAdapter(GrpcUserService service) {
        this.grpcService = service;
    }
    
    @Override
    public User getUser(String id) {
        // 转换REST请求为gRPC请求
        UserRequest request = UserRequest.newBuilder()
            .setUserId(id)
            .build();
        
        // 调用gRPC服务
        UserProto response = grpcService.getUser(request);
        
        // 转换gRPC响应为REST响应
        return new User(response.getName(), response.getEmail());
    }
}

5.4 系统集成开发

java 复制代码
// 外部服务接口(如支付网关)
interface ExternalPaymentService {
    void makePayment(String merchantId, BigDecimal amount);
}

// 内部支付接口
interface InternalPaymentService {
    void pay(PaymentDetails details);
}

// 支付网关适配器
class PaymentGatewayAdapter implements InternalPaymentService {
    private ExternalPaymentService externalService;
    
    @Override
    public void pay(PaymentDetails details) {
        externalService.makePayment(
            Config.getMerchantId(),
            details.amount()
        );
    }
}

5.5 API版本兼容

java 复制代码
// V1 API
@Deprecated
class UserServiceV1 {
    User getUserById(int id) { ... }
}

// V2 API
class UserServiceV2 {
    Optional<User> findUser(String uuid) { ... }
}

// 版本适配器
class UserServiceAdapter extends UserServiceV2 {
    private UserServiceV1 legacyService;
    
    public Optional<User> findUser(String uuid) {
        try {
            int id = Integer.parseInt(uuid);
            return Optional.ofNullable(legacyService.getUserById(id));
        } catch (NumberFormatException e) {
            return super.findUser(uuid);
        }
    }
}

5.6 设备驱动开发

java 复制代码
// 标准打印机接口
interface Printer {
    void print(Document doc);
}

// 旧型号打印机
class DotMatrixPrinter {
    void printRaw(String text) { ... }
}

// 打印机适配器
class DotMatrixPrinterAdapter implements Printer {
    private DotMatrixPrinter printer = new DotMatrixPrinter();
    
    @Override
    public void print(Document doc) {
        printer.printRaw(doc.toPlainText());
    }
}

6.性能优化策略

6.1 适配器缓存机制

java 复制代码
class CachingAdapter implements NewInterface {
    private OldService oldService;
    private Map<String, Object> responseCache = new ConcurrentHashMap<>();
    
    public Result performOperation(String param) {
        // 缓存命中检查
        if (responseCache.containsKey(param)) {
            return (Result) responseCache.get(param);
        }
        
        // 转换调用
        LegacyResult legacyResult = oldService.legacyOperation(param);
        Result result = convertResult(legacyResult);
        
        // 更新缓存
        responseCache.put(param, result);
        return result;
    }
}

6.2 批量请求适配

java 复制代码
class BatchAdapter implements ModernAPI {
    private LegacyService legacy;
    private List<Request> batchBuffer = new ArrayList<>();
    
    public void asyncProcess(Request request) {
        batchBuffer.add(request);
        if (batchBuffer.size() >= 50) {
            flushBatch();
        }
    }
    
    private void flushBatch() {
        LegacyBatchRequest batch = new LegacyBatchRequest();
        for (Request req : batchBuffer) {
            batch.add(convertRequest(req));
        }
        
        legacy.processBatch(batch);
        batchBuffer.clear();
    }
}

7.Java生态中的经典应用

7.1 JDK集合框架适配

java 复制代码
// 数组到List的适配
String[] array = {"Java", "Adapter", "Pattern"};
List<String> list = Arrays.asList(array);

// Enumeration到Iterator的适配
Enumeration<String> enumeration = ...;
Iterator<String> iterator = new EnumerationIterator(enumeration);

7.2 IO流系统适配

java 复制代码
// 字节流到字符流的适配
InputStream is = new FileInputStream("data.txt");
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);

// 原始数据流适配
DataInputStream dis = new DataInputStream(is);
int intValue = dis.readInt();
double doubleValue = dis.readDouble();

7.3 Spring框架中的适配器

java 复制代码
// HandlerAdapter实现
public class AnnotationHandlerAdapter implements HandlerAdapter {
    public boolean supports(Object handler) {
        return handler instanceof Controller;
    }
    
    public ModelAndView handle(HttpServletRequest request, 
                              HttpServletResponse response, 
                              Object handler) {
        // 调用Controller方法
        return ((Controller)handler).handleRequest(request, response);
    }
}

// 消息转换器
public class MappingJackson2HttpMessageConverter 
    implements HttpMessageConverter<Object> {
    // JSON与Java对象转换
}

8.反模式与陷阱规避

8.1 适配器滥用场景

  • 不兼容程度过高:接口语义完全不同时
  • 性能敏感场景:多层适配导致调用链过长
  • 过度封装:隐藏了本应暴露的重要差异
  • 适配器嵌套:多个适配器串联增加复杂度

8.2 陷阱解决方案

java 复制代码
// 问题:多重适配导致调试困难
class OverlyComplexAdapter {
    // 方案:使用组合替代嵌套
    private Service primaryAdapter;
    private Service fallbackAdapter;
    
    void execute() {
        try {
            primaryAdapter.execute();
        } catch (UnsupportedOperationException e) {
            fallbackAdapter.execute(); // 降级策略
        }
    }
}

9.扩展演进:现代变体

9.1 函数式适配器(Java 8+)

java 复制代码
// 函数接口适配
class FunctionalAdapter {
    private final Function<Request, LegacyRequest> requestAdapter;
    private final Function<LegacyResponse, Response> responseAdapter;
    
    public Response execute(Request request) {
        LegacyRequest legacyReq = requestAdapter.apply(request);
        LegacyResponse legacyRes = legacyService.process(legacyReq);
        return responseAdapter.apply(legacyRes);
    }
}

// Lambda实现适配逻辑
FunctionalAdapter adapter = new FunctionalAdapter(
    req -> new LegacyRequest(req.getId(), req.getData()),
    res -> new Response(res.getCode(), res.getBody())
);

9.2 反应式适配器(Project Reactor)

java 复制代码
public class ReactiveAdapter {
    private final LegacyReactiveService legacy;
    
    public Flux<TargetOutput> process(Flux<TargetInput> inputStream) {
        return inputStream
            .map(this::toLegacyInput)  // 输入适配
            .flatMap(legacy::process)  // 调用遗留服务
            .map(this::toTargetOutput) // 输出适配
            .onErrorResume(this::handleErrors); // 错误适配
    }
}

10.实战案例:支付网关集成

java 复制代码
// 统一支付接口
interface PaymentGateway {
    PaymentResult pay(PaymentRequest request);
}

// PayPal适配器
class PayPalAdapter implements PaymentGateway {
    private final PayPalService paypal;
    
    public PaymentResult pay(PaymentRequest request) {
        // 转换参数
        PayPalPayment paypalReq = new PayPalPayment(
            request.getAmount(),
            request.getCurrency(),
            request.getCustomerEmail()
        );
        
        // 调用PayPal
        PayPalResponse response = paypal.makePayment(paypalReq);
        
        // 转换响应
        return new PaymentResult(
            response.isSuccess() ? Status.SUCCESS : Status.FAILED,
            response.getTransactionId()
        );
    }
}

// Stripe适配器
class StripeAdapter implements PaymentGateway {
    private final StripeService stripe;
    
    public PaymentResult pay(PaymentRequest request) {
        StripeCharge charge = new StripeCharge.Builder()
            .setAmount(request.getAmountInCents())
            .setCurrency(request.getCurrency().name())
            .setSource(request.getToken())
            .build();
        
        Charge stripeCharge = stripe.charge(charge);
        return new PaymentResult(
            stripeCharge.getStatus() == SUCCEEDED ? 
                Status.SUCCESS : Status.FAILED,
            stripeCharge.getId()
        );
    }
}

// 使用示例
PaymentGateway gateway = new PayPalAdapter(new PayPalService());
PaymentResult result = gateway.pay(request);

11.模式关系图谱

增强功能 简化接口 分离抽象 适配器模式 装饰器模式 外观模式 桥接模式 动态添加行为 复杂子系统 多种实现

关键区别:

  • 适配器 vs 装饰器:适配器改变接口,装饰器增强功能
  • 适配器 vs 外观:适配器解决接口兼容,外观简化复杂接口
  • 适配器 vs 桥接:适配器事后补救,桥接事前设计

12.总结:适配器模式的核心价值

适配器模式作为系统集成的接口转换层,在以下场景展现不可替代的价值:

场景 适配器作用 实现要点
系统迁移 新旧模块兼容 接口转换
第三方集成 统一接口规范 协议转换
跨平台开发 屏蔽平台差异 实现适配
接口演进 多版本共存 版本转换

🚀 架构启示:适配器模式不仅是代码级解决方案,更是架构设计的关键思想:

  1. 在微服务架构中作为协议转换层
  2. 在中台系统中作为能力适配层
  3. 在遗留系统改造中作为防腐层
  4. 在云原生架构中作为Sidecar适配器
  5. 在全球化系统中作为本地化适配器
    🚀 终极设计原则:适配器不是简单的代码技巧,而是系统架构中的战略层设计,管理差异不是消除差异,而是优雅地协调差异共存。
相关推荐
一叶飘零_sweeeet1 小时前
Java+EasyExcel 打造学习平台视频学习时长统计系统
java·报表·easyexcel
Go away, devil1 小时前
Java-----集合
java·开发语言
JIngJaneIL1 小时前
旅游|内蒙古景点旅游|基于Springboot+Vue的内蒙古景点旅游管理系统设计与实现(源码+数据库+文档)
java·vue.js·spring boot·论文·旅游·毕设·内蒙古景点旅游
新之助小锅2 小时前
java版连接汇川PLC,发送数据,读取数据,保持重新链接,适用安卓
android·java·python
无糖冰可乐214 小时前
IDEA多java版本切换
java·ide·intellij-idea
合作小小程序员小小店4 小时前
web开发,在线%超市销售%管理系统,基于idea,html,jsp,java,ssh,sql server数据库。
java·前端·sqlserver·ssh·intellij-idea
brucelee1864 小时前
IntelliJ IDEA 设置 Local History 永久保留
java·ide·intellij-idea
Pluto_CSND6 小时前
Java中的静态代理与动态代理(Proxy.newProxyInstance)
java·开发语言
o0向阳而生0o6 小时前
112、23种设计模式之命令模式(20/23)
设计模式·命令模式