【TS 设计模式完全指南】TypeScript 装饰器模式的优雅之道

一、什么是装饰器模式?

装饰器模式(Decorator Pattern)是一种结构型设计模式 ,它允许你在不修改现有对象结构 的情况下,动态地为对象添加新的功能。它通过将对象包装在一个"装饰器"对象中来实现,这个装饰器对象提供了与原对象相同的接口,并增加了额外的行为。

二、装饰器模式的核心组件

  1. 组件 (Component):定义了原始对象和装饰器对象的共同接口。客户端代码将通过这个接口与所有对象(无论是否被装饰)进行交互。
  2. 具体组件 (Concrete Component):这是我们要装饰的原始对象,它实现了组件接口。
  3. 基础装饰器 (Base Decorator):一个抽象类,它也实现了组件接口。它内部持有一个对另一个"组件"对象的引用(可以是具体组件,也可以是另一个装饰器)。它的主要职责是将所有请求转发给被包装的对象。
  4. 具体装饰器 (Concrete Decorator):继承自基础装饰器,负责为组件添加特定的新功能。它会在转发请求之前或之后执行自己的附加逻辑。

三、示例:打造一个多渠道通知器

3.1 定义组件接口 (Component)

这是所有通知器都必须遵守的契约。

typescript 复制代码
// Component: 通知器的统一接口
interface INotifier {
    send(message: string): void;
}

3.2 创建具体组件 (Concrete Component)

这是我们的基础,最核心的通知功能。

typescript 复制代码
// Concrete Component: 基础通知器,只打印到控制台
class BaseNotifier implements INotifier {
    send(message: string): void {
        console.log(`[站内信]:发送消息 - "${message}"`);
    }
}

3.3 创建基础装饰器 (Base Decorator)

这个抽象类是所有装饰器的父类,它负责"包装"和"代理"。

typescript 复制代码
// Base Decorator: 装饰器基类
abstract class NotifierDecorator implements INotifier {
    protected wrappedNotifier: INotifier;

    constructor(notifier: INotifier) {
        this.wrappedNotifier = notifier;
    }

    // 将 send 请求委托给被包装的对象
    send(message: string): void {
        this.wrappedNotifier.send(message);
    }
}

3.4. 创建具体装饰器 (Concrete Decorators)

现在来制作我们的实际业务:发送短信和邮件

typescript 复制代码
// Concrete Decorator 1: 短信通知装饰器
class SMSDecorator extends NotifierDecorator {
    send(message: string): void {
        super.send(message); // 首先调用原始的 send 方法
        console.log(`[短信]:发送消息 - "${message}"`);
    }
}

// Concrete Decorator 2: 邮件通知装饰器
class EmailDecorator extends NotifierDecorator {
    send(message: string): void {
        super.send(message); // 调用原始方法
        console.log(`[邮件]:发送消息 - "${message}"`);
    }
}

注意 super.send(message) 的调用,它确保了包装链上的原始功能得以执行。你也可以把自己的逻辑放在它前面,实现前置处理。

3.5 自由组合,动态增强!

现在,我们可以像搭积木一样,自由地组合这些功能。

typescript 复制代码
const message = '您的订单已发货!';

// 1. 只需要一个基础通知器
console.log('--- 基础通知 ---');
const basicNotifier = new BaseNotifier();
basicNotifier.send(message);

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

// 2. 我需要站内信 + 短信
console.log('--- 站内信 + 短信 ---');
let notifierWithSMS = new BaseNotifier();
notifierWithSMS = new SMSDecorator(notifierWithSMS);
notifierWithSMS.send(message);

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

// 3. 我需要站内信 + 短信 + 邮件
console.log('--- 站内信 + 短信 + 邮件 ---');
let notifierWithAll = new BaseNotifier();
notifierWithAll = new SMSDecorator(notifierWithAll);
notifierWithAll = new EmailDecorator(notifierWithAll);
notifierWithAll.send(message);

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

// 4. 还可以有更疯狂的组合:站内信 + 邮件 + 再次短信(如果业务需要)
console.log('--- 疯狂组合 ---');
let crazyNotifier: INotifier = new BaseNotifier();
crazyNotifier = new EmailDecorator(crazyNotifier);
crazyNotifier = new SMSDecorator(crazyNotifier);
crazyNotifier.send('系统即将维护,请注意!');

运行结果:

ini 复制代码
--- 基础通知 ---
[站内信]:发送消息 - "您的订单已发货!"

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

--- 站内信 + 短信 ---
[站内信]:发送消息 - "您的订单已发货!"
[短信]:发送消息 - "您的订单已发货!"

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

--- 站内信 + 短信 + 邮件 ---
[站内信]:发送消息 - "您的订单已发货!"
[短信]:发送消息 - "您的订单已发货!"
[邮件]:发送消息 - "您的订单已发货!"

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

--- 疯狂组合 ---
[站内信]:发送消息 - "系统即将维护,请注意!"
[邮件]:发送消息 - "系统即将维护,请注意!"
[短信]:发送消息 - "系统即将维护,请注意!"

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

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

总结

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

相关推荐
YaeZed2 小时前
TypeScript7(元组)
typescript
闲云野鹤_2 小时前
typeScript学习笔记总结(常用)
typescript
aidingni8882 小时前
掌握 JavaScript 中的 Map 和 Set
前端·javascript
闲云野鹤_3 小时前
JavaScript学习笔记
javascript
努力往上爬de蜗牛3 小时前
react3面试题
javascript·react.js·面试
之恒君3 小时前
TypeScript(tsconfig.json - references)
typescript
开心不就得了3 小时前
React 进阶
前端·javascript·react.js
jeff渣渣富3 小时前
Taro 2.x 分包优化实践:如何防止分包文件被打包到主包
前端·javascript
wow_DG3 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(八):Vuex 内部机制
前端·javascript·vue.js