← 返回首页
🧩

适配器模式:协议转换与遗留集成

📂 architecture ⏱ 2 min 275 words

适配器模式:协议转换与遗留集成

适配器模式概述

适配器模式将一个类的接口转换成客户端期望的另一个接口,使原本接口不兼容的类可以一起工作。在架构设计中,适配器模式是系统集成的核心手段,解决不同系统间的协议差异、数据格式差异和接口差异。

// 目标接口
public interface PaymentProcessor {
    PaymentResult process(PaymentRequest request);
}

// 适配器 - 将第三方支付网关适配到统一接口
public class AlipayAdapter implements PaymentProcessor {
    private final AlipayClient alipayClient;
    
    public PaymentResult process(PaymentRequest request) {
        // 转换请求格式
        AlipayTradePayRequest aliRequest = new AlipayTradePayRequest();
        aliRequest.setOutTradeNo(request.getOrderId());
        aliRequest.setTotalAmount(request.getAmount().toString());
        aliRequest.setSubject(request.getDescription());
        
        // 调用支付宝API
        AlipayTradePayResponse aliResponse = alipayClient.execute(aliRequest);
        
        // 转换响应格式
        return PaymentResult.builder()
            .success("10000".equals(aliResponse.getCode()))
            .transactionId(aliResponse.getTradeNo())
            .message(aliResponse.getSubMsg())
            .build();
    }
}

协议转换适配器

不同系统可能使用不同的通信协议,适配器模式统一协议差异。例如将HTTP REST适配为gRPC,或适配消息队列协议。

# HTTP到gRPC协议适配器
class HTTPToGRPCAdapter:
    def __init__(self, grpc_stub):
        self.stub = grpc_stub
    
    async def handle_http_request(self, http_request: dict) -> dict:
        # HTTP JSON -> Protobuf转换
        grpc_request = CreateOrderRequest(
            user_id=http_request['userId'],
            items=[
                OrderItem(
                    product_id=item['productId'],
                    quantity=item['quantity']
                )
                for item in http_request['items']
            ],
            total_amount=Decimal(str(http_request['totalAmount']))
        )
        
        # 调用gRPC服务
        grpc_response = await self.stub.CreateOrder(grpc_request)
        
        # Protobuf -> HTTP JSON转换
        return {
            'orderId': grpc_response.order_id,
            'status': grpc_response.status.name,
            'createdAt': grpc_response.created_at.isoformat()
        }

遗留系统封装

将遗留系统的接口封装为现代化接口,新系统通过适配器访问遗留系统,避免大规模重构。

// 遗留系统适配器 - 封装老旧COM组件
public class LegacyInventoryAdapter : IInventoryService
{
    private readonly COMInventoryLibrary.LegacyInventory _legacySystem;
    
    public LegacyInventoryAdapter()
    {
        _legacySystem = new COMInventoryLibrary.LegacyInventory();
    }
    
    public async Task<StockInfo> GetStock(string productId)
    {
        // 转换新接口到遗留接口格式
        var legacyResult = _legacySystem.CheckStock(productId, "WAREHOUSE01");
        
        // 转换遗留接口返回值
        return new StockInfo
        {
            ProductId = productId,
            Quantity = legacyResult.QtyAvailable,
            Warehouse = legacyResult.WarehouseCode,
            LastUpdated = DateTime.FromFileTime(legacyResult.UpdateTime)
        };
    }
    
    public async Task<bool> DeductStock(string productId, int quantity)
    {
        var result = _legacySystem.ReserveStock(productId, quantity, "SYSTEM");
        return result.ReturnCode == 0;
    }
}

多数据源统一适配

使用适配器模式统一不同数据源的访问接口,实现透明的数据源切换和多数据源聚合。

// 统一存储适配器接口
type StorageAdapter interface {
    Get(ctx context.Context, key string) ([]byte, error)
    Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
    Delete(ctx context.Context, key string) error
}

// Redis适配器
type RedisAdapter struct {
    client *redis.Client
}

func (r *RedisAdapter) Get(ctx context.Context, key string) ([]byte, error) {
    return r.client.Get(ctx, key).Bytes()
}

// 本地缓存适配器
type LocalCacheAdapter struct {
    cache *cache.Cache
}

func (l *LocalCacheAdapter) Get(ctx context.Context, key string) ([]byte, error) {
    val, found := l.cache.Get(key)
    if !found {
        return nil, ErrKeyNotFound
    }
    return val.([]byte), nil
}