TypeScript中的SOLID原则:理论与实践示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么SOLID在TypeScript中很重要



SOLID是罗伯特·马丁(Bob大叔)提出的五个面向对象设计基本原则的首字母缩写。在TypeScript的上下文中,这些原则因其严格的类型系统和对现代OOP范式的支持而具有特殊价值。应用SOLID原则能使代码更加灵活、可测试且易于维护,这对可扩展项目至关重要。



在本文中,我们将通过TypeScript的实际示例来解析每个SOLID原则,展示反模式及其正确实现。您将学习如何编写在添加新功能时不会出错的代码。



1. Single Responsibility Principle (SRP) — 单一职责原则



理论

每个类应该只有一个引起变化的原因。这意味着一个类应该只负责程序功能的一个部分。如果一个类执行多个任务,它将更难维护和测试。



反模式(违反SRP)

class UserService {    saveUser(user: User): void {        // 保存到数据库        console.log('User saved');    }

sendEmail(user: User, message: string): void { // 发送邮件 console.log(`Email sent to ${user.email}`); }

generateReport(user: User): string { // 生成报告 return `Report for ${user.name}`; }}


正确实现(SRP)

class UserRepository {    save(user: User): void {        // 仅保存    }}

class EmailService { send(user: User, message: string): void { // 仅发送邮件 }}

class ReportGenerator { generate(user: User): string { // 仅生成报告 }}


2. Open-Closed Principle (OCP) — 开闭原则



理论

类应该对扩展开放,对修改关闭。新功能应通过继承或组合来添加,而不是修改现有代码。



反模式(违反OCP)

class PaymentProcessor {    processPayment(type: string, amount: number): void {        if (type === 'card') {            // 处理信用卡        } else if (type === 'paypal') {            // 处理PayPal        } else if (type === 'crypto') {            // 处理加密货币        }        // 添加新类型时——需要修改类!    }}


正确实现(OCP)

interface PaymentMethod {    process(amount: number): void;}

class CardPayment implements PaymentMethod { process(amount: number): void { console.log(`Processing card payment: $${amount}`); }}

class PayPalPayment implements PaymentMethod { process(amount: number): void { console.log(`Processing PayPal payment: $${amount}`); }}

class PaymentProcessor { constructor(private paymentMethod: PaymentMethod) {}

process(amount: number): void { this.paymentMethod.process(amount); }}


3. Liskov Substitution Principle (LSP) — 里氏替换原则



理论

基类对象应能被其子类对象替换,而不影响程序的正确性。子类不应改变基类的预期行为。



反模式(违反LSP)

class Rectangle {    constructor(public width: number, public height: number) {}

setWidth(width: number): void { this.width = width; }

setHeight(height: number): void { this.height = height; }

getArea(): number { return this.width * this.height; }}

class Square extends Rectangle {

博客

书籍推荐