Loading...
Loading...
Compare original and translation side by side
| Principle | One-liner | Apply when... | Skip when... |
|---|---|---|---|
| SRP | One reason to change | A module mixes unrelated concerns | Splitting creates indirection with no clarity gain |
| OCP | Extend, don't modify | You need plugin-style variation | You're still discovering requirements |
| LSP | Subtypes must be substitutable | Building type hierarchies | Using composition instead |
| ISP | Small, focused interfaces | Clients depend on methods they don't use | Interface has natural cohesion |
| DIP | Depend on abstractions | You need testability or swappable implementations | Only one implementation exists or will ever exist |
| DRY | Single source of truth | Identical logic with identical reasons to change | Similar-looking code with different reasons to change |
| KISS | Simplest solution that works | Always the default | Never skip this |
| YAGNI | Don't build it until you need it | Tempted to add "just in case" features | Building foundational APIs with known extension points |
| 原则 | 一句话总结 | 适用场景 | 避免场景 |
|---|---|---|---|
| SRP | 单一变更原因 | 模块混杂了不相关的职责 | 拆分后会增加间接性且无清晰度提升 |
| OCP | 扩展而非修改 | 需要插件式变体的场景 | 仍在探索需求的阶段 |
| LSP | 子类型必须可替换 | 构建类型层级结构时 | 改用组合方式实现时 |
| ISP | 小而聚焦的接口 | 客户端依赖了未使用的方法时 | 接口具有自然内聚性时 |
| DIP | 依赖抽象而非具体实现 | 需要可测试性或可替换实现的场景 | 仅存在一种实现且未来也不会有其他实现时 |
| DRY | 单一事实来源 | 逻辑完全相同且变更原因一致的场景 | 外观相似但变更原因不同的代码 |
| KISS | 最简单的可行方案 | 始终作为默认选择 | 绝不跳过此原则 |
| YAGNI | 无需则不构建 | 想要添加“以防万一”的功能时 | 构建已知有扩展点的基础API时 |
| Pattern | Best for | Avoid when |
|---|---|---|
| Clean/Hexagonal | Long-lived systems with complex domains | Simple CRUD apps, prototypes |
| DDD | Complex business logic with domain experts | Technical/infrastructure-heavy systems |
| Event-Driven | Decoupled workflows, audit trails | Simple request/response flows |
| CQRS | Read/write asymmetry, complex queries | Uniform read/write patterns |
| Monolith-first | New projects, small teams | Already proven need for independent deployment |
| Microservices | Independent team deployment at scale | Small team, shared database, tight coupling |
| 模式 | 最佳适用场景 | 避免场景 |
|---|---|---|
| Clean/Hexagonal | 生命周期长、领域复杂的系统 | 简单CRUD应用、原型 |
| DDD | 业务逻辑复杂且有领域专家参与的系统 | 偏重技术/基础设施的系统 |
| Event-Driven | 解耦的工作流、审计追踪 | 简单的请求/响应流程 |
| CQRS | 读写不对称、复杂查询 | 读写模式统一的场景 |
| Monolith-first | 新项目、小团队 | 已明确需要独立部署的场景 |
| Microservices | 大规模下团队独立部署的场景 | 小团队、共享数据库、高耦合的系统 |
| Smell | Likely violation | Remedy |
|---|---|---|
| God class / function | SRP | Extract cohesive responsibilities |
| Shotgun surgery (one change touches many files) | Low cohesion | Colocate related logic |
| Feature envy (method uses another object's data more than its own) | Misplaced responsibility | Move method to the data owner |
| Primitive obsession | Missing domain concept | Introduce a value type |
| Deep inheritance trees | Favoring inheritance over composition | Flatten with composition/interfaces |
| Boolean parameters | SRP, OCP | Split into separate functions |
| Speculative generality | YAGNI | Delete unused abstractions |
| 设计异味 | 可能违反的原则 | 解决方法 |
|---|---|---|
| 上帝类/上帝函数 | SRP | 提取具有内聚性的职责 |
| 霰弹式修改(一次变更涉及多个文件) | 低内聚 | 将相关逻辑集中放置 |
| 特性羡慕(方法更多使用其他对象的数据而非自身数据) | 职责错位 | 将方法移至数据所属对象 |
| 原始类型痴迷 | 缺失领域概念 | 引入值类型 |
| 深层继承树 | 偏好继承而非组合 | 用组合/接口扁平化结构 |
| 布尔参数 | SRP、OCP | 拆分为独立函数 |
| 投机性通用设计 | YAGNI | 删除未使用的抽象 |