正在加载,请稍候…

TypeScript 中的 SOLID 原则:实用示例

通过真实的 TypeScript 示例掌握五大 SOLID 原则,学习 SRP、OCP、LSP、ISP 和 DIP 如何提升代码可维护性

TypeScript 中的 SOLID 原则:实用示例

TypeScript 中的 SOLID 原则:实用示例

SOLID 原则指导你编写灵活、可维护的面向对象代码。

单一职责原则(SRP)

一个类应该只有一个引起变化的原因。

// 糟糕:同时处理用户数据和邮件发送
class UserService {
  createUser(name: string, email: string) { /* ... */ }
  sendWelcomeEmail(email: string) { /* ... */ }
  generateReport() { /* ... */ }
}

// 良好:分离职责
class UserRepository {
  create(user: User): Promise<User> { /* ... */ }
  findById(id: string): Promise<User> { /* ... */ }
}

class EmailService {
  sendWelcome(email: string): Promise<void> { /* ... */ }
}

class UserReportGenerator {
  generate(): Report { /* ... */ }
}

TypeScript 中的 SOLID 原则:实用示例 插图

开闭原则(OCP)

对扩展开放,对修改关闭。

// 糟糕:添加折扣类型需要修改类
class OrderCalculator {
  calculate(order: Order): number {
    if (order.type === 'regular') return order.total;
    if (order.type === 'premium') return order.total * 0.9;
    // 新增类型必须修改类
  }
}

// 良好:通过扩展实现,无需修改
interface DiscountStrategy {
  apply(total: number): number;
}

class RegularDiscount implements DiscountStrategy {
  apply(total: number) { return total; }
}

class PremiumDiscount implements DiscountStrategy {
  apply(total: number) { return total * 0.9; }
}

class BlackFridayDiscount implements DiscountStrategy {
  apply(total: number) { return total * 0.7; }
}

class OrderCalculator {
  constructor(private discount: DiscountStrategy) {}
  calculate(order: Order): number {
    return this.discount.apply(order.total);
  }
}

TypeScript 中的 SOLID 原则:实用示例 插图

里氏替换原则(LSP)

子类型必须能够替换其基类型。

// 糟糕:Square 破坏了 Rectangle 的约定
class Rectangle {
  setWidth(w: number) { this.width = w; }
  setHeight(h: number) { this.height = h; }
  area() { return this.width * this.height; }
}

class Square extends Rectangle {
  setWidth(w: number) { this.width = w; this.height = w; } // 违反 LSP!
}

// 良好:分离层次结构
interface Shape {
  area(): number;
}
class Rectangle implements Shape { /* ... */ }
class Square implements Shape { /* ... */ }

TypeScript 中的 SOLID 原则:实用示例 插图

接口隔离原则(ISP)

客户端不应依赖它们不使用的接口。

// 糟糕:臃肿的接口
interface Worker {
  work(): void;
  eat(): void;
  sleep(): void;
}

// 良好:小而专注的接口
interface Workable { work(): void; }
interface Eatable { eat(): void; }
interface Sleepable { sleep(): void; }

class Human implements Workable, Eatable, Sleepable { /* ... */ }
class Robot implements Workable { /* 只工作 */ }

依赖倒置原则(DIP)

依赖抽象,而非具体实现。

// 糟糕:依赖具体实现
class OrderService {
  private db = new MySQLDatabase(); // 硬依赖
  saveOrder(order: Order) { this.db.save(order); }
}

// 良好:依赖抽象
interface Database {
  save<T>(data: T): Promise<void>;
  find<T>(id: string): Promise<T>;
}

class OrderService {
  constructor(private db: Database) {} // 注入
  async saveOrder(order: Order) { await this.db.save(order); }
}

// 在应用根组合
const service = new OrderService(new PostgresDatabase());

SOLID 原则使系统更易于测试、扩展和维护。