TypeScript 设计模式

设计模式是前人总结的、针对常见问题的可复用解法。TypeScript 拥有接口、抽象类、泛型与访问修饰符,让"面向接口编程"真正落地。本节用 TS 实现四个高频模式:单例、工厂、观察者、策略。

单例模式

单例保证一个类全局只有一个实例,常用于配置中心、日志器。用 private 构造器阻止外部 new:

class Logger {
  private static instance: Logger;
  private constructor() {} // 禁止外部直接 new
  static getInstance(): Logger {
    if (!Logger.instance) Logger.instance = new Logger();
    return Logger.instance;
  }
  log(msg: string): void {
    console.log(`[LOG] ${msg}`);
  }
}

Logger.getInstance().log("hello"); // 输出:[LOG] hello
Logger.getInstance().log("again"); // 输出:[LOG] again

可自行验证 Logger.getInstance() === Logger.getInstance() 为 true,两次拿到的是同一个对象。

工厂模式

工厂把"创建哪个对象"的决策集中起来,调用方只依赖抽象接口,新增产品类型时无需改动调用方:

interface Shape {
  area(): number;
}
class Circle implements Shape {
  constructor(private r: number) {}
  area(): number { return Math.PI * this.r * this.r; }
}
class Square implements Shape {
  constructor(private side: number) {}
  area(): number { return this.side * this.side; }
}
function shapeFactory(kind: "circle" | "square", size: number): Shape {
  return kind === "circle" ? new Circle(size) : new Square(size);
}

console.log(shapeFactory("circle", 2).area()); // 输出:12.566370614359172
console.log(shapeFactory("square", 2).area()); // 输出:4

观察者(发布订阅)模式

对象间"松耦合"通信:主题状态变化时通知所有订阅者,泛型让事件数据保持类型安全:

type Handler<T> = (data: T) => void;
class EventBus<T> {
  private handlers: Handler<T>[] = [];
  on(h: Handler<T>): void { this.handlers.push(h); }
  emit(data: T): void { this.handlers.forEach((h) => h(data)); }
}

const bus = new EventBus<string>();
bus.on((m) => console.log("订阅者1收到:", m));
bus.on((m) => console.log("订阅者2收到:", m));
bus.emit("更新了"); // 输出:订阅者1收到: 更新了 / 订阅者2收到: 更新了

策略模式

把可替换的算法各自封装成对象,运行时自由切换,消除大量 if/else:

interface SortStrategy {
  sort(data: number[]): number[];
}
const asc: SortStrategy = { sort: (d) => [...d].sort((a, b) => a - b) };
const desc: SortStrategy = { sort: (d) => [...d].sort((a, b) => b - a) };
function runSort(data: number[], s: SortStrategy): number[] {
  return s.sort(data);
}

console.log(runSort([3, 1, 2], asc));  // 输出:[1, 2, 3]
console.log(runSort([3, 1, 2], desc)); // 输出:[3, 2, 1]

小结

单例管全局唯一、工厂隔离创建逻辑、观察者解耦通知、策略替换算法。TS 的接口与泛型让这些模式在编译期就被固定下来,比 JS 时代的实现更可靠、更好维护。

笔记加载中…