DEV Community

WDSEGA
WDSEGA

Posted on

TypeScript设计模式精讲:用现代TS写出优雅可维护的代码

TypeScript设计模式

引言

设计模式是软件工程中的"最佳实践模板"。在前端TypeScript项目中,合理运用设计模式能让代码更优雅、更可维护。本文精选8个最实用的设计模式。

1. 观察者模式

type EventMap = {
  'user:login': { userId: string; timestamp: number };
  'cart:update': { items: CartItem[]; total: number };
};

class TypedEventEmitter<Events extends Record<string, any>> {
  private listeners = new Map<keyof Events, Set<Function>>();

  on<K extends keyof Events>(event: K, callback: (data: Events[K]) => void): () => void {
    if (!this.listeners.has(event)) this.listeners.set(event, new Set());
    this.listeners.get(event)!.add(callback);
    return () => this.off(event, callback);
  }

  emit<K extends keyof Events>(event: K, data: Events[K]): void {
    this.listeners.get(event)?.forEach(cb => cb(data));
  }
}
Enter fullscreen mode Exit fullscreen mode

2. 策略模式

interface ValidationStrategy {
  validate(value: string): string | null;
}

class FormValidator {
  private strategies = new Map<string, ValidationStrategy[]>();

  addField(field: string, ...strategies: ValidationStrategy[]): this {
    this.strategies.set(field, strategies);
    return this;
  }

  validate(formData: Record<string, string>): Record<string, string[]> {
    const errors: Record<string, string[]> = {};
    for (const [field, validators] of this.strategies) {
      const fieldErrors = validators
        .map(v => v.validate(formData[field] ?? ''))
        .filter((e): e is string => e !== null);
      if (fieldErrors.length > 0) errors[field] = fieldErrors;
    }
    return errors;
  }
}
Enter fullscreen mode Exit fullscreen mode

3. 工厂模式

class ChartFactory {
  private static registry = new Map<ChartType, new (config: ChartConfig) => Chart>();

  static register(type: ChartType, creator: new (config: ChartConfig) => Chart): void {
    this.registry.set(type, creator);
  }

  static create(config: ChartConfig): Chart {
    const Creator = this.registry.get(config.type);
    if (!Creator) throw new Error(`Unknown: ${config.type}`);
    return new Creator(config);
  }
}
Enter fullscreen mode Exit fullscreen mode

4. 装饰器模式

function Memoize(target: any, key: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  const cache = new Map<string, any>();
  descriptor.value = function (...args: any[]) {
    const cacheKey = JSON.stringify(args);
    if (cache.has(cacheKey)) return cache.get(cacheKey);
    const result = original.apply(this, args);
    cache.set(cacheKey, result);
    return result;
  };
  return descriptor;
}
Enter fullscreen mode Exit fullscreen mode

5. 适配器模式

interface PaymentGateway {
  charge(amount: number, currency: string): Promise<{ transactionId: string }>;
}

class StripeAdapter implements PaymentGateway {
  async charge(amount: number, currency: string) {
    const pi = await this.stripe.paymentIntents.create({
      amount: Math.round(amount * 100), currency: currency.toLowerCase()
    });
    return { transactionId: pi.id };
  }
}
Enter fullscreen mode Exit fullscreen mode

6. 责任链模式

abstract class Middleware {
  private next: Middleware | null = null;
  setNext(m: Middleware): Middleware { this.next = m; return m; }
  handle(req: Request): Response | null {
    return this.next?.handle(req) ?? null;
  }
}
Enter fullscreen mode Exit fullscreen mode

何时使用

模式 适用场景
观察者 一对多依赖
策略 算法可互换
工厂 复杂对象创建
装饰器 动态添加功能
适配器 接口不兼容
单例 全局唯一
责任链 多步骤处理
代理 延迟加载

结语

设计模式的关键是理解背后的思想,而不是死记硬背模板代码。


📢 本文为精简版,完整版包含独家工具推荐和深度分析,请访问 WD Tech Blog 查看!

关注我的博客获取最新科技资讯、AI教程和效率工具推荐!

Top comments (0)