其他
从零设计或重构 Python 服务/组件时…
适用于设计新组件、重构 God class/巨石函数、决定是否抽象、选择继承或组合、评估 PR 结构问题,或因 I/O 与业务逻辑纠缠而难以测试的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 55/100 ×0.15
适用场景
从零设计或重构 Python 服务/组件通用
解决思路
- 选择能工作的最简单方案;任何复杂度都必须由具体需求证明其必要性(KISS)。
- 让每个单元只有一个变更原因;按关注点拆分为职责聚焦的组件(SRP)。
- 通过组合对象来构建行为,而不是通过扩展类来获得行为(组合优于继承)。
- 等到同一逻辑出现三次再抽象;重复通常优于过早抽象(Rule of Three)。
- 用简单查表/映射代替不必要的工厂或注册表模式,例如 `FORMATTERS = {"json": JsonFormatter, "csv": CsvFormatter}`,然后 `def get_formatter(name: str) -> Formatter: return FORMATTERS[name]()`。
- 需要更详细的模式说明和工作示例时,阅读 `references/details.md`。
- 保持函数小:约 20-50 行(按复杂度调整),且只做一件事。
- 通过构造函数注入依赖,以提升可测试性。
- 抽象之前先删除死代码,然后再考虑是否引入模式。
- 为每个关注点/层编写隔离测试。
- 显式优于取巧:可读代码优先于“优雅”代码。
- 分离关注点:不同层有清晰且单一的目的。
- 当类变大且疑似多职责时,用“变更原因”测试:列出所有可能导致修改该类的变更;若变更来自不同领域(如 HTTP 解析、业务规则、格式化),就拆分;若都来自同一领域关注点,则类的大小可能合适。
- 当构造函数参数达到 7 个以上时,先拆分该类中过多的职责,而不是否定构造函数注入;拆完后每个构造函数自然变小。
- 当组合导致难以追踪的深层嵌套包装对象时,把组合保持在浅层(2-3 层);若包装是唯一机制,考虑基于 Protocol 的方式或简单函数组合。
- 若 Rule of Three 建议暂不抽象,但重复副本已危险地分叉(改一个漏一个并引发 bug),则立即抽取共享行为,并添加覆盖共享行为的测试。
- 若 service 层导入 API 层,视为分层违规并修复:service 层不得从 handlers 导入;引入共享 types/models 层供二者导入,保持依赖方向向下(API → Service → Repository)。
适用边界 · 注意事项
- 当重复尚未达到三次且没有具体需求时,不要急于抽象或引入设计模式。
- 当一个类的所有变更原因都来自同一领域关注点时,不要为了“更小”而强行拆分。
- 不要构建超过 2-3 层的深层组合包装链;如果只剩包装机制,先考虑 Protocol 或函数组合。