My App

适配器模式

Adapter — 把不兼容的接口转换成客户端期望的接口

一句话理解

在两个不兼容的接口之间加一个转换器,让它们能协同工作。就像电源适配器把 220V 转成 5V 一样。

解决什么问题

  • 想复用一个已有的类,但它的接口和你需要的不一致
  • 对接第三方库/旧系统,接口不匹配
  • 不想(或不能)修改已有代码

怎么写

场景:系统期望的是 Target 接口,但已有的类是 Adaptee,接口不匹配。

// 客户端期望的接口
public interface Target {
    void request();
}

// 已有的类,接口不兼容
public class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee 的特殊方法");
    }
}

// 适配器:实现目标接口,内部委托给 Adaptee
public class Adapter implements Target {
    private final Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        // 把调用转发给 Adaptee
        adaptee.specificRequest();
    }
}
// 使用:客户端只面向 Target 接口
Target target = new Adapter(new Adaptee());
target.request();  // 内部调用了 Adaptee.specificRequest()

实际例子:对接多种支付

// 统一支付接口
public interface PayService {
    void pay(double amount);
}

// 支付宝 SDK(第三方,接口不同)
public class AlipaySDK {
    public void sendPayment(double money) { /* ... */ }
}

// 适配器
public class AlipayAdapter implements PayService {
    private final AlipaySDK sdk = new AlipaySDK();

    @Override
    public void pay(double amount) {
        sdk.sendPayment(amount);  // 转换调用
    }
}

前端中的适配器

// 后端返回的数据格式和前端组件期望的不一致
// 适配器函数做转换
function adaptUserData(apiData: ApiUser): ComponentUser {
  return {
    id: apiData.user_id,          // user_id -> id
    fullName: apiData.full_name,  // full_name -> fullName
    avatar: apiData.avatar_url,   // avatar_url -> avatar
  }
}

使用场景

  • Java I/O:InputStreamReader 把字节流适配成字符流
  • Spring MVC:HandlerAdapter 把不同类型的 Handler 适配到统一的处理流程
  • 前端数据转换层(API 响应 → 组件 Props)
  • 旧系统改造中的接口兼容层

On this page