关于 oop-best-practices
面向日常编码与代码评审的面向对象设计技能,帮助提升可读性、对象职责划分和长期可维护性,并提供多种语言的参考资料。
主要功能
- 01命名与抽象设计指导
- 02封装与对象职责检查
- 03基于消息的对象协作
- 04组合优于继承的实践
- 05代码评审工作流
- 06多语言示例与参考资料
适用场景
- 01评审类职责与接口边界
- 02改进含混的命名和抽象
- 03为领域对象确定行为归属
- 04在日常重构中简化对象协作
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ luckys/ agent-skills --skill oop-best-practices安装后在 Claude Code 中输入/oop-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/advanced-modeling-concepts.mdbook-influences.mdchange-driven-design.mdcore-principles.mdcsharp-examples.mddependency-management.mddomain-language-and-modeling.mdfran-iglesias-practical-guidance.mdgo-examples.mdgradual-abstraction.mdinterface-depth.mdjava-examples.mdlanguage-examples.mdmessage-based-design.mdmethod-design.mdnaming-and-abstractions.mdobject-calisthenics.mdoop-good-practices-examples.mdphp-examples.mdpython-examples.mdruby-examples.mdrust-examples.mdsimple-design-rules.mdsolid-principles.mdthird-party-notices.mdtypescript-examples.mdvalue-objects-advanced.md详细介绍
面向对象编程最佳实践
在日常编码决策中使用此技能,以提升代码的可读性、内聚性和长期可维护性。
尤其适用于以下情况:
- 需要更好的命名和更明确的抽象
- 需要厘清对象职责并封装不变量
- 需要基于消息的协作和面向角色的对象
- 在日常设计选择中优先采用组合而非继承
工作方式
- 编写代码时要考虑下一位阅读者,而不仅仅是编译器。
- 让行为贴近拥有该行为的概念。
- 优先采用简单的协作方式,而非精巧复杂的对象图。
- 通过命名、边界和 API 揭示意图。
- 在对象能够承载自身规则时,就让它们自己承载。
审查工作流
-
识别概念。
- 这段代码在建模什么概念?
- 哪些规则或不变量属于这个概念?
-
检查边界。
- 对象暴露的是原始数据,还是有意义的行为?
- 调用方是否不得不深入了解过多内部结构?
-
检查结构。
- 方法是否混杂了多个抽象层次?
- 类是否承担了不止一种变更原因?
- 命名是否足够明确,能让人快速理解意图?
-
采用最轻量且有效的改进方式。
- 重命名以提高清晰度
- 提取方法
- 提取值对象
- 提取一等集合
- 将行为移至拥有数据的对象
- 按职责拆分类
其他审查视角
命名与抽象规范
- 如果名称不够明确,应先审视抽象,再润色措辞。
- 避免过早抽象,以免抹去概念或过度猜测未来的复用需求。
- 消除重复的知识,而不只是重复的语法。
封装与对象职责
- 将规则移至拥有这些规则的概念中。
- 当概念具有有意义的行为时,优先使用丰富对象,而非数据载体。
- 对象能够持有规则时,让服务负责协调。
基于消息的设计
- 优先请求协作者执行有意义的行为,而非从中取出数据。
- 依赖角色和消息,而非具体的内部结构。
- 保持公共接口精简、明确且能清晰表达意图。
结构简洁性
- 当行为会独立变化时,优先使用组合。
- 让继承层次保持浅显且名副其实。
- 避免让人不得不逐层穿越的复杂对象图。
日常规则
- 优先使用能清晰表达意图的名称,而非简短名称。
- 保持方法层次清晰,并专注于单一抽象层次。
- 在减少分支干扰时使用提前返回。
- 保持类的内聚性,而不只是追求小巧。
- 当身份无关紧要,且语义保证、类型安全或行为足以证明领域类型合理时,引入值对象。
- 优先告知协作者要做什么,而不是索取其数据并在其他地方做出判断。
- 当集合具有自身不变量时,引入一等集合。
- 为值对象提供语义相等性、匹配的哈希行为和深度不可变的观察方式;不要依赖对象引用相等性或浅层的
readonly。 - 依赖小而明确的角色,而非易变的具体细节。
- 当行为会独立变化时,优先使用组合。
- 让公共 API 比内部实现细节更精简。
良好信号
- 类名与其负责的行为相符。
- 无效状态会被尽早拒绝。
- 大多数方法无需阅读无关辅助代码就能理解。
- 调用方依赖的接口面很小。
- 同一概念在整个代码库中的命名保持一致。
警示信号
- 一个方法需要好几条注释才能读懂。
- 一个类主要由 getter 和 setter 组成。
- 许多调用方重复相同的验证或分支逻辑。
- 一个概念的变更迫使你修改许多互不相关的文件。
- 对象模型看起来只是数据传输,行为却被附加在其他地方。
参考资料
-
评估接口复杂度、透传层或调用方必须跟踪的状态时,请阅读
references/interface-depth.md。 -
阅读
references/core-principles.md,了解精简的编码启发。 -
阅读
references/book-influences.md,了解这项技能背后关键书籍的来源导览。 -
命名或抽象质量是主要问题时,请阅读
references/naming-and-abstractions.md。 -
对象协作和角色最重要时,请阅读
references/message-based-design.md。 -
阅读
references/advanced-modeling-concepts.md,了解仍适用于日常 OO 设计的丰富对象选择。 -
阅读
references/fran-iglesias-practical-guidance.md,了解从 Fran Iglesias 的内容中提炼出的实用 OO 启发。 -
SOLID 违规,或围绕单一职责、开闭原则或依赖倒置的设计压力是主要问题时,请阅读
references/solid-principles.md。 -
对类或方法应用严格的 OO 规范规则以进行清理时,请阅读
references/object-calisthenics.md。 -
关注耦合、依赖方向或协作者注入决策时,请阅读
references/dependency-management.md。 -
方法长度、抽象层次或表达意图的结构存在问题时,请阅读
references/method-design.md。 -
不清楚何时该引入抽象,或设计过早过度工程化时,请阅读
references/gradual-abstraction.md。 -
阅读
references/language-examples.md,获取特定语言示例文件(TypeScript、Java、Python、C#、Ruby、PHP、Go、Rust)的索引。 -
阅读
references/go-examples.md,了解 Go 中的 OOP 概念(结构体、隐式接口、组合、无继承)。 -
阅读
references/rust-examples.md,了解 Rust 中的 OOP 概念(结构体、trait、newtype 模式、将所有权视为不可变性)。 -
阅读
references/simple-design-rules.md,了解 Kent Beck 的简单设计 4 条规则:通过测试、表达意图、没有重复、元素最少,并附有 CodelyTV 示例。 -
阅读
references/oop-good-practices-examples.md,了解经过修正的跨语言经验,涵盖迪米特法则、Tell Don't Ask、命名式构造、集合身份、依赖角色和课程中的反例。 -
将
references/value-objects-advanced.md作为值对象的权威指南:选择标准、不变量归属、构造与解析、相等性和哈希、深度不可变性、行为、可选性、一等集合、持久化、测试和安全演进。
相关技能
- 当对象所有权同时定义一致性、生命周期、仓储或事务边界时,使用
ddd-best-practices。 - 进行值对象契约测试、边界分析、基于属性的测试和确定性测试夹具时,使用
tdd-best-practices。 - 变更有风险或涉及遗留代码时,使用
refactoring-best-practices。 - 主要问题是模式选择时,使用
design-patterns-best-practices。 - 设计用于公开这些对象的 HTTP API 接口时,使用
rest-api-best-practices。
来源影响
这项技能综合了以下内容所强调的理念:
- Carlos Blé 的
Sustainable Code - Kent Beck 的
Implementation Patterns - Sandi Metz 的
Practical Object-Oriented Design in Ruby - Sandi Metz 的
99 Bottles of OOP - Fran Iglesias 的
design-principles文章 - Fran Iglesias 的
good-practices文章 - Fran Iglesias 的
Object Calisthenics系列 - CodelyTV OOP Good Practices 课程(包括渐进式和被覆盖的教学反例)
- CodelyTV Aggregates 课程
- CodelyTV Value Objects 课程
- CodelyTV 简单设计四条规则课程(包括关于有意命名、YAGNI、接口、重复和测试的反例)