【TS 设计模式完全指南】用适配器模式优雅地“兼容”一切

一、什么是适配器模式?

适配器模式(Adapter Pattern)是一种结构型设计模式 ,它的核心思想是:将一个类的接口转换成客户端所期望的另一个接口。 这使得原本因接口不兼容而无法协同工作的类可以一起工作。

二、适配器模式的核心组件

  • 目标 (Target) :这是客户端代码所期待和依赖的接口。在TypeScript中,我们通常用 interface 来定义它。
  • 被适配者 (Adaptee):这是已经存在的、但接口与目标不兼容的类或对象。它是"需要被适配"的角色。
  • 适配器 (Adapter) :这是模式的核心。它实现了 目标 (Target) 接口,并在内部持有对 被适配者 (Adaptee) 的引用。当客户端调用适配器的方法时,适配器会将其转换为对被适配者方法的调用。

三、示例:构建一个支付适配器

3.1 定义目标接口 (Target)

这是我们系统内部期望的支付接口,简洁明了。

typescript 复制代码
// Target: 我们系统期望的支付接口
interface PaymentProcessor {
    processPayment(amount: number): void;
}

我们的客户端代码会像这样使用它:

typescript 复制代码
class Store {
    private paymentProcessor: PaymentProcessor;

    constructor(processor: PaymentProcessor) {
        this.paymentProcessor = processor;
    }

    purchaseItem(price: number) {
        console.log(`准备购买一件价格为 ${price} 的商品...`);
        this.paymentProcessor.processPayment(price);
    }
}

3.2 引入"不兼容"的被适配者 (Adaptee)

现在,我们需要集成两个第三方的支付服务:PayPalStripe。不幸的是,它们的API设计和我们的 PaymentProcessor 完全不同。

typescript 复制代码
// Adaptee 1: Ios 的支付服务
class IosPaymentGateway {
    public sendPayment(total: number, currency: string): void {
        console.log(`Ios平台 支付了 ${currency} ${total}`);
    }
}

// Adaptee 2: android 的支付服务
class AndroidGateway {
    public submitTransaction(value: number, description: string): boolean {
        console.log(`android 平台 支付了 ${description}, 金额: ${value}`);
        return true; // 表示交易成功
    }
}
  • 可以看到ios平台和Android平台的支付参数不一致

3.3 创建适配器 (Adapter)

现在,轮到我们的主角------适配器登场了。我们将为 IosAndroid 分别创建一个适配器。

为 Ios 创建适配器:

typescript 复制代码
// Adapter for Ios
class IosAdapter implements PaymentProcessor {
    private iosGateway: IosPaymentGateway;

    constructor() {
        this.iosGateway = new IosPaymentGateway();
    }

    processPayment(amount: number): void {
        // 将我们简单的 processPayment 调用,转换为复杂的 sendPayment 调用
        console.log('适配器正在转换 ios 支付请求...');
        this.iosGateway.sendPayment(amount, 'USD');
    }
}

为 Android 创建适配器:

typescript 复制代码
// Adapter for Android
class AndroidAdapter implements PaymentProcessor {
    private androidGateway: AndroidGateway;

    constructor() {
        this.androidGateway = new AndroidGateway();
    }

    processPayment(amount: number): void {
        // 将 processPayment 调用,转换为 submitTransaction 调用
        console.log('适配器正在转换 android 支付请求...');
        this.androidGateway.submitTransaction(amount, '商品购买');
    }
}

3.4 将它们组合在一起

现在,我们的 Store 类可以无缝地使用任何一种支付方式,而完全不需要知道 IosAndroid 的内部细节。

typescript 复制代码
// 使用 Ios 支付
const iosAdapter = new IosAdapter();
const storeWithPayPal = new Store(iosAdapter);
storeWithPayPal.purchaseItem(100);

console.log('\n' + '='.repeat(30) + '\n');

// 切换到 Android 支付,Store 类代码无需任何修改!
const androidAdapter = new AndroidAdapter();
const storeWithStripe = new Store(androidAdapter);
storeWithStripe.purchaseItem(75);

运行结果:

erlang 复制代码
准备购买一件价格为 100 的商品...
适配器正在转换 ios 支付请求...
Ios平台 支付了 USD 100

==============================

准备购买一件价格为 75 的商品...
适配器正在转换 android 支付请求...
android 平台 支付了 商品购买, 金额: 75

为了方便大家学习和实践,本文的所有示例代码和完整项目结构都已整理上传至我的 GitHub 仓库。欢迎大家克隆、研究、提出 Issue,共同进步!

📂 核心代码与完整示例: GoF

总结

如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript/TypeScript开发干货

相关推荐
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
书院门前细致的苹果10 小时前
设计模式大全:单例、工厂模式、策略模式、责任链模式
设计模式·责任链模式·策略模式
铅笔侠_小龙虾11 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
大模型玩家七七12 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
2501_9447114312 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜13 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
阔皮大师13 小时前
INote轻量文本编辑器
java·javascript·python·c#
lbb 小魔仙13 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js
_codemonster13 小时前
Vue的三种使用方式对比
前端·javascript·vue.js