关于 solid-principles
面向面向对象系统的软件设计技能,通过示例、反模式和排查建议讲解 SOLID 原则。适用于大型代码库的设计,不面向简单脚本或函数式编程。
主要功能
- 01讲解 SOLID 五项原则
- 02识别常见设计反模式
- 03按原则提供排查建议
- 04提供 TypeScript 代码示例
适用场景
- 01重构承担多种职责的类
- 02扩展功能而不反复修改现有类
- 03改进可替换性与接口设计
- 04降低高层代码对具体依赖的耦合
MCP 相关
该技能提及使用 `mcp__documentation__fetch_docs` 获取完整的 SOLID Principles 文档。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill solid-principles安装后在 Claude Code 中输入/solid-principles确认已加载。
详细介绍
SOLID 原则
深入了解:使用
mcp__documentation__fetch_docs,并将 technology 设为:solid-principles,以获取全面的文档。
何时不应使用此技能
此技能侧重于 OOP 设计原则。以下情况请勿使用:
- 函数式编程——SOLID 主要面向 OOP,请改用函数式编程专用模式
- 简单脚本/实用工具——SOLID 会增加复杂度;请用于较大型的系统
- 性能关键型代码——抽象开销可能影响性能
- 通用代码质量——请使用
clean-code技能处理命名、函数和可读性
反模式
| 反模式 | 违反的原则 | 解决方案 |
|---|---|---|
| 上帝类 | SRP | 拆分为职责单一、侧重点明确的类 |
| 按类型使用 Switch | OCP | 使用多态和策略模式 |
| 在子类中抛出异常 | LSP | 确保子类遵循基类契约 |
| 臃肿的接口 | ISP | 拆分为更小、面向特定角色的接口 |
| 到处使用 new 关键字 | DIP | 使用依赖注入,依赖抽象 |
| 脆弱的基类 | LSP、OCP | 优先使用组合而非继承 |
| 标记接口 | ISP | 使用包含有意义方法的恰当抽象 |
快速故障排除
| 问题 | 原则 | 修复方法 |
|---|---|---|
| 类因多个原因而发生变化 | SRP | 为每项职责提取单独的类 |
| 添加功能必须修改类 | OCP | 通过接口/抽象使类可扩展 |
| 子类导致父类测试失败 | LSP | 确保子类可以顺利替代父类 |
| 需要实现空方法 | ISP | 将接口拆分为更小、侧重点明确的接口 |
| 具体依赖导致难以测试 | DIP | 通过接口注入依赖 |
| 无法替换实现 | DIP | 依赖抽象,而非具体实现 |
S - 单一职责
// ❌ Bad - Multiple responsibilities
class User {
save() { /* database logic */ }
sendEmail() { /* email logic */ }
generateReport() { /* report logic */ }
}
// ✅ Good - Single responsibility each
class User { /* user data only */ }
class UserRepository { save(user: User) { } }
class EmailService { send(to: string, message: string) { } }
class ReportGenerator { generate(user: User) { } }
O - 开闭原则
// ❌ Bad - Modify class to add new payment
class PaymentProcessor {
process(payment: Payment) {
if (payment.type === 'credit') { /* ... */ }
else if (payment.type === 'paypal') { /* ... */ }
// Must modify to add new type
}
}
// ✅ Good - Extend without modification
interface PaymentMethod {
process(amount: number): Promise<void>;
}
class CreditCardPayment implements PaymentMethod { }
class PayPalPayment implements PaymentMethod { }
class CryptoPayment implements PaymentMethod { } // New, no changes needed
L - 里氏替换原则
// ❌ Bad - Square can't substitute Rectangle
class Rectangle {
setWidth(w: number) { this.width = w; }
setHeight(h: number) { this.height = h; }
}
class Square extends Rectangle {
setWidth(w: number) { this.width = this.height = w; } // Breaks expectation
}
// ✅ Good - Use composition or separate abstractions
interface Shape {
getArea(): number;
}
class Rectangle implements Shape { }
class Square implements Shape { }
I - 接口隔离原则
// ❌ Bad - Fat interface
interface Worker {
work(): void;
eat(): void;
sleep(): void;
}
class Robot implements Worker {
eat() { throw new Error('Robots dont eat'); } // Forced to implement
}
// ✅ Good - Segregated interfaces
interface Workable { work(): void; }
interface Eatable { eat(): void; }
interface Sleepable { sleep(): void; }
class Human implements Workable, Eatable, Sleepable { }
class Robot implements Workable { }
D - 依赖倒置原则
// ❌ Bad - High-level depends on low-level
class UserService {
private db = new MySQLDatabase(); // Concrete dependency
}
// ✅ Good - Depend on abstractions
interface Database {
query(sql: string): Promise<any>;
}
class UserService {
constructor(private db: Database) { } // Injected abstraction
}
// Can use any implementation
new UserService(new MySQLDatabase());
new UserService(new PostgresDatabase());
new UserService(new MockDatabase()); // For testing
权威来源
- Robert C. Martin 著《SOLID Principles》- https://blog.cleancoder.com/uncle-bob/2020/10/18/Solid-Relevance.html
- Robert C. Martin 著《Agile Software Development》- https://www.oreilly.com/library/view/agile-software-development/0135974445/
参考文档
评论
支持 Markdown