目录
- 1.模式概述
- 2.模式结构解析
-
- [2.1 UML类图详解](#2.1 UML类图详解)
- [2.2 核心角色职责](#2.2 核心角色职责)
- 3.两种实现范式
-
- [3.1 UML类图对比](#3.1 UML类图对比)
- [3.2 对象适配器 vs 类适配器](#3.2 对象适配器 vs 类适配器)
- [3.3 代码实现对比](#3.3 代码实现对比)
- 4.适配器模式变体
-
- [4.1 双向适配器](#4.1 双向适配器)
- [4.2 参数适配器](#4.2 参数适配器)
- 5.应用场景深度探索
-
- [5.1 遗留系统集成](#5.1 遗留系统集成)
- [5.2 跨平台UI组件适配](#5.2 跨平台UI组件适配)
- [5.3 微服务协议转换](#5.3 微服务协议转换)
- [5.4 系统集成开发](#5.4 系统集成开发)
- [5.5 API版本兼容](#5.5 API版本兼容)
- [5.6 设备驱动开发](#5.6 设备驱动开发)
- 6.性能优化策略
-
- [6.1 适配器缓存机制](#6.1 适配器缓存机制)
- [6.2 批量请求适配](#6.2 批量请求适配)
- 7.Java生态中的经典应用
-
- [7.1 JDK集合框架适配](#7.1 JDK集合框架适配)
- [7.2 IO流系统适配](#7.2 IO流系统适配)
- [7.3 Spring框架中的适配器](#7.3 Spring框架中的适配器)
- 8.反模式与陷阱规避
-
- [8.1 适配器滥用场景](#8.1 适配器滥用场景)
- [8.2 陷阱解决方案](#8.2 陷阱解决方案)
- 9.扩展演进:现代变体
-
- [9.1 函数式适配器(Java 8+)](#9.1 函数式适配器(Java 8+))
- [9.2 反应式适配器(Project Reactor)](#9.2 反应式适配器(Project Reactor))
- 10.实战案例:支付网关集成
- 11.模式关系图谱
- 12.总结:适配器模式的核心价值
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.总结:适配器模式的核心价值
适配器模式作为系统集成的接口转换层,在以下场景展现不可替代的价值:
| 场景 | 适配器作用 | 实现要点 |
|---|---|---|
| 系统迁移 | 新旧模块兼容 | 接口转换 |
| 第三方集成 | 统一接口规范 | 协议转换 |
| 跨平台开发 | 屏蔽平台差异 | 实现适配 |
| 接口演进 | 多版本共存 | 版本转换 |
🚀 架构启示:适配器模式不仅是代码级解决方案,更是架构设计的关键思想:
- 在微服务架构中作为协议转换层
- 在中台系统中作为能力适配层
- 在遗留系统改造中作为防腐层
- 在云原生架构中作为Sidecar适配器
- 在全球化系统中作为本地化适配器
🚀 终极设计原则:适配器不是简单的代码技巧,而是系统架构中的战略层设计,管理差异不是消除差异,而是优雅地协调差异共存。