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 对象适配器(推荐方式)

// 目标接口
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中通过继承实现)

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

4.适配器模式变体

4.1 双向适配器

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 参数适配器

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 遗留系统集成

// 旧版订单系统
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组件适配

// 安卓组件
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 微服务协议转换

// 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 系统集成开发

// 外部服务接口(如支付网关)
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版本兼容

// 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 设备驱动开发

// 标准打印机接口
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 适配器缓存机制

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 批量请求适配

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集合框架适配

// 数组到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流系统适配

// 字节流到字符流的适配
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框架中的适配器

// 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 陷阱解决方案

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

9.扩展演进:现代变体

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

// 函数接口适配
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)

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.实战案例:支付网关集成

// 统一支付接口
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. 在全球化系统中作为本地化适配器

终极设计原则:适配器不是简单的代码技巧,而是系统架构中的战略层设计,管理差异不是消除差异,而是优雅地协调差异共存。

posted @ 2025-12-11 19:53  clnchanpin  阅读(5)  评论(0)    收藏  举报