TypeScript中的SOLID原则:进阶理论与实践
SOLID是面向对象设计的五个基本原则,它们能够帮助创建灵活、可维护且可扩展的代码。在TypeScript中,得益于强类型、接口和抽象类,这些原则的实现尤为高效。本文将通过TypeScript的实际示例,在进阶层面逐一剖析每个原则。
1. 单一职责原则(SRP)
理论:每个类应该只有一个修改原因。在TypeScript中,这意味着一个模块只负责一项功能。
进阶实践:违反SRP通常表现为“上帝对象”(God Objects)。应使用组合和委托。
// ❌ 违反SRP:该类同时负责数据、验证和持久化class UserService { constructor(private user: User) {}
validateEmail(email: string): boolean { return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email); }
saveToDatabase(): void { // 保存逻辑 }
sendWelcomeEmail(): void { // 发送逻辑 }}
// ✅ SRP:分离职责interface IEmailValidator { isValid(email: string): boolean;}
interface IUserRepository { save(user: User): Promise<void>;}
interface INotificationService { sendWelcome(user: User): Promise<void>;}
class UserRegistrationService { constructor( private validator: IEmailValidator, private repository: IUserRepository, private notifier: INotificationService ) {}
async register(user: User): Promise<void> { if (!this.validator.isValid(user.email)) { throw new Error('无效邮箱'); } await this.repository.save(user); await this.notifier.sendWelcome(user); }}2. 开闭原则(OCP)
理论:类应对扩展开放,对修改关闭。在TypeScript中,通过抽象类和接口实现。
进阶实践:使用“策略模式”(Strategy)来实现OCP。
// ❌ 违反OCP:添加新报告类型时需要修改类class ReportGenerator { generate(data: any[], type: string): string { if (type === 'csv') { return data.map(row => row.join(',')).join(''); } else if (type === 'json') { return JSON.stringify(data); } // 添加 'xml' 时——需修改此方法 throw new Error('不支持的格式'); }}
// ✅ OCP:使用多态interface IReportFormatter { format(data: any[]): string;}
class CsvFormatter implements IReportFormatter { format(data: any[]): string { return data.map(row => row.join(',')).join(''); }}
class JsonFormatter implements IReportFormatter { format(data: any[]): string { return JSON.stringify(data); }}
class XmlFormatter implements IReportFormatter { format(data: any[]): string { // XML实现 return '<data>...</data>'; }}
class ReportGeneratorOCP { constructor(private formatter: IReportFormatter) {}
generate(data: any[]): string { return this.formatter.format(data); }}
// 使用:无需修改即可扩展const csvReport = new ReportGeneratorOCP(new CsvFormatter());const jsonReport = new ReportGeneratorOCP(new JsonFormatter());3. 里氏替换原则(LSP)
理论:程序中的对象应可被其子类型的实例替换,而不影响程序的正确性。在TypeScript中,由于名义类型系统,这一点尤为关键。