关于 design-patterns
面向开发者的设计模式参考技能,帮助选择并应用成熟模式。按问题和代码症状组织内容,并强调结合实际场景使用,而非照搬模板。
主要功能
- 01按问题和症状选择模式
- 02基础设计原则
- 03常见类别的模式参考
- 04反模式与误用指导
- 05实现检查清单
适用场景
- 01为反复出现的设计问题选择模式
- 02根据代码症状识别适用模式
- 03检查设计是否存在过度工程化
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ratacat/ claude-skills --skill design-patterns安装后在 Claude Code 中输入/design-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
patterns/adapter.mdbuilder.mdchain-of-responsibility.mdcommand.mdcomposite.mddecorator.mddto.mdfacade.mdfactory.mdidentity-map.mdlazy-load.mdmediator.mdobserver.mdproxy.mdrepository.mdservice-layer.mdstate.mdstrategy.mdtemplate-method.mdunit-of-work.md详细介绍
设计模式
概览
设计模式是针对反复出现的软件设计问题而经过验证的解决方案。它们提供了一套用于讨论设计的通用词汇,并汇集了数十年来在实际应用中不断打磨的集体智慧。
核心理念: 模式是需要根据具体情境调整的模板,而不是照搬的蓝图。只有在确实能简化设计时才使用合适的模式,而不是为了炫技或过度设计。
基础原则
这些原则是所有优秀设计的基石:
| 原则 | 含义 | 违反原则的表现 |
|---|---|---|
| 封装变化点 | 将变化的部分与稳定的部分隔离 | 更改会波及整个代码库 |
| 面向接口编程 | 依赖抽象,而非具体实现 | 无法替换实现 |
| 组合优于继承 | 通过组合对象来构建行为 | 类层次结构过深且僵化 |
| 松耦合 | 尽量减少对象之间的相互依赖 | 改动一处就会导致另一处出问题 |
| 开闭原则 | 对扩展开放,对修改关闭 | 添加新功能时必须修改现有代码 |
| 单一职责 | 每个类只有一个变更理由 | 类承担的职责过多 |
| 依赖倒置 | 高层模块不依赖低层模块 | 业务逻辑与基础设施耦合 |
模式选择指南
按问题类型
CREATING OBJECTS
├── Complex/conditional creation ──────────→ Factory Method
├── Families of related objects ───────────→ Abstract Factory
├── Step-by-step construction ─────────────→ Builder
├── Clone existing objects ────────────────→ Prototype
└── Single instance needed ────────────────→ Singleton (use sparingly!)
STRUCTURING/COMPOSING OBJECTS
├── Incompatible interface ────────────────→ Adapter
├── Simplify complex subsystem ────────────→ Facade
├── Tree/hierarchy structure ──────────────→ Composite
├── Add behavior dynamically ──────────────→ Decorator
└── Control access to object ──────────────→ Proxy
MANAGING COMMUNICATION/BEHAVIOR
├── One-to-many notification ──────────────→ Observer
├── Encapsulate requests as objects ───────→ Command
├── Behavior varies by internal state ─────→ State
├── Swap algorithms at runtime ────────────→ Strategy
├── Algorithm skeleton with hooks ─────────→ Template Method
├── Reduce N-to-N communication ───────────→ Mediator
└── Sequential handlers ───────────────────→ Chain of Responsibility
MANAGING DATA ACCESS
├── Abstract data source ──────────────────→ Repository
├── Track changes for atomic commit ───────→ Unit of Work
├── Ensure object identity ────────────────→ Identity Map
├── Defer expensive loading ───────────────→ Lazy Load
├── Map objects to database ───────────────→ Data Mapper
└── Shape data for transfer ───────────────→ DTO
按症状
| 症状 | 可考虑 |
|---|---|
| 基于类型的巨大 switch/if-else | Strategy、State 或多态 |
| 类之间存在重复代码 | Template Method、Strategy |
| 需要通知许多对象发生的变更 | Observer |
| 对象创建逻辑复杂 | Factory、Builder |
| 添加功能导致类臃肿 | Decorator |
| 第三方 API 与代码不兼容 | Adapter |
| 组件之间存在过多依赖 | Mediator、Facade |
| 没有数据库或网络就无法测试 | Repository、Dependency Injection |
| 需要撤销/重做 | Command |
| 对象行为取决于状态 | State |
| 请求需要由多个处理程序处理 | Chain of Responsibility |
领域逻辑:Transaction Script 与 Domain Model
| 因素 | Transaction Script | Domain Model |
|---|---|---|
| 逻辑复杂度 | 简单(< 500 行) | 复杂,规则众多 |
| 业务规则 | 较少且直观 | 众多且相互作用 |
| 操作 | 以 CRUD 为主 | 行为丰富 |
| 团队/时间线 | 小团队,快速交付 | 长期维护 |
| 测试 | 集成测试 | 针对领域的单元测试 |
经验法则: 从 Transaction Script 开始。当过程式代码变得难以维护时,再重构为 Domain Model。
快速参考
第 1 级:必备模式(优先掌握)
| 模式 | 一句话说明 | 适用场景 | 参考 |
|---|---|---|---|
| Strategy | 封装可互换的算法 | 同一任务有多种实现方式,且需要在运行时切换 | strategy.md |
| Observer | 在状态变化时通知依赖方 | 事件系统、响应式更新 | observer.md |
| Factory | 封装对象创建 | 复杂或有条件的实例化 | factory.md |
| Decorator | 动态添加行为 | 无需继承即可扩展 | decorator.md |
| Command | 将请求封装为对象 | 撤销/重做、排队、日志记录 | command.md |
第 2 层:结构型模式
| 模式 | 一句话说明 | 适用场景 | 参考 |
|---|---|---|---|
| Adapter | 转换接口 | 集成不兼容的代码 | adapter.md |
| Facade | 简化复杂子系统 | 通过简单 API 隐藏复杂性 | facade.md |
| Composite | 统一树形结构 | 整体—部分层次结构 | composite.md |
| Proxy | 控制对对象的访问 | 延迟加载、访问控制、缓存 | proxy.md |
第 3 层:企业级/架构模式
| 模式 | 一句话说明 | 适用场景 | 参考 |
|---|---|---|---|
| Repository | 类集合式的数据访问 | 解耦领域层与数据层 | repository.md |
| Unit of Work | 协调原子性变更 | 事务管理 | unit-of-work.md |
| Service Layer | 编排业务操作 | 定义应用边界 | service-layer.md |
| DTO | 定义传输数据的结构 | API 契约、防止过度暴露 | dto.md |
其他重要模式
| 模式 | 一句话说明 | 适用场景 | 参考 |
|---|---|---|---|
| Builder | 分步骤构建对象 | 复杂对象、流式 API | builder.md |
| State | 行为随状态变化 | 状态机、工作流 | state.md |
| Template Method | 带钩子的算法骨架 | 框架扩展点 | template-method.md |
| Chain of Responsibility | 沿处理器传递请求 | 中间件、管道 | chain-of-responsibility.md |
| Mediator | 集中处理复杂通信 | 降低组件耦合 | mediator.md |
| Lazy Load | 延迟执行开销较大的加载 | 性能、大型对象图 | lazy-load.md |
| Identity Map | 确保对象标识唯一 | ORM、防止重复 | identity-map.md |
常见错误
| 错误 | 表现 | 修正方法 |
|---|---|---|
| 过度使用模式 | 简单操作也需要在许多类之间辗转 | 仅在解决实际问题时使用 |
| 模式错误 | 代码显得生硬、别扭 | 重新审视实际问题 |
| 滥用继承 | 层次结构过深、基类脆弱 | 优先使用组合(Strategy、Decorator) |
| 滥用 Singleton | 全局状态、隐藏依赖、难以测试 | 改用依赖注入 |
| 过早抽象 | 接口只有一个实现 | 等到确有变化需求时再抽象 |
需要识别的反模式
- 上帝对象: 一个类包办所有事情 → 按 SRP 拆分
- 贫血领域模型: 对象只是数据包 → 将行为移到对象中
- 金锤: 到处使用同一种模式 → 根据问题选择模式
- 熔岩流: 无人清理的死代码 → 删除它,版本控制系统会为你兜底
现代变体
| 现代模式 | 基于 | 描述 |
|---|---|---|
| Dependency Injection | Strategy + Factory | 容器创建并注入依赖 |
| Middleware | Decorator + Chain of Responsibility | 请求/响应管道 |
| Event Sourcing | Command | 将状态变更存储为事件 |
| CQRS | Command/Query 分离 | 分离读写模型 |
| Hooks (React/Vue) | Observer + Strategy | 函数式生命周期订阅 |
实现检查清单
实现模式之前:
- 该模式能解决此代码库中的实际问题
- 已考虑更简单的替代方案
- 权衡取舍适合当前场景
- 团队理解该模式
- 不会过度设计解决方案
评论
支持 Markdown