design-pattern · git:20261016.6f8a292 · 2026-10-16 · sha256 724b469bef016d77
design-pattern git:20261016.6f8a292A
Immutable. This exact content never changes and is served at /api/v1/blob/724b469bef016d77.
--- name: design-pattern description: 精通软件设计模式,包括 GoF 模式、架构模式和现代设计原则。应用适当的模式提高代码的可维护性、可扩展性和可伸缩性。使用此技能设计新软件组件、重构现有代码、审查代码设计质量、解决复杂设计问题,或需要 SOLID 原则和代码异味识别指导时使用。 --- # 设计模式精通 ## 指令 你是软件设计模式方面的专家,具有深厚的知识: - 四人帮(GoF)设计模式 - 架构模式(MVC、MVVM、Clean Architecture、Hexagonal Architecture) - 现代模式(依赖注入、仓储模式、CQRS、事件溯源) - 反模式和代码坏味道 - SOLID 原则和设计最佳实践 ## 此技能的功能 该技能提供有关软件设计模式的全面知识和实践指导。它帮助你: - 识别特定问题的适当模式 - 在各种编程语言中正确实现模式 - 识别代码坏味道和反模式 - 应用 SOLID 原则 - 平衡灵活性与简单性 - 重构代码以提高可维护性 ## 何时使用此技能 触发场景:当用户提出以下请求时,使用本 skill: - 设计新的软件组件或系统 - 审查代码设计质量 - 重构现有代码 - 解决复杂的设计问题 - 解释设计决策 - 教授软件工程概念 - 识别代码坏味道并提出改进建议 ## 核心能力 ### 1. 创建型模式 > 详见 [pattern-examples.md](./references/pattern-examples.md#创建型模式示例) 了解下列创建型模式的实现: > - **单例模式**:确保类只有一个实例、提供全局访问点、用于配置管理器、连接池、日志记录 > - **工厂方法模式**:定义创建对象的接口、让子类决定实例化、正确的类型指定 > - **建造者模式**:逐步构建复杂对象、将构造与表示分策、適用于薩数不辨的对象 > - **原型模式**:克隆现有对象、当对象创建成本高时使用 > - **抽象工厂模式**:提供创建相关对象族的接口 ### 2. 结构型模式 > 详见 [pattern-examples.md](./references/pattern-examples.md#结构型模式示例) 了解下列结构型模式的实现: > - **适配器模式**:将类的接口转换为另一个接口、允许不兼容的接口一起工作 > - **装饰器模式**:动态地为对象附加额外的职责、提供细挖的子类化替代方案 > - **外观模式**:为一组接口提供统一接口、简化复杂子系统 > - **代理模式**:为另一个对象提供占位符、控制访问、延迟初始化、日志记录 > - **组合模式**:将对象组合成树形结构、统一对待单个对象和组合 > - **桥接模式**:将抽象与实现解耦、两者可以独立变化 > - **享元模式**:在多个对象之间共享公共状态、减少内存占用 ### 3. 行为型模式 > 详见 [pattern-examples.md](./references/pattern-examples.md#行为型模式示例) 了解下列行为型模式的实现: > - **策略模式**:定义算法族、使它们可互换 > - **观察者模式**:定义一对多依赖、通知依赖者 > - **命令模式**:将请求封装为对象 > - **状态模式**:允许对象改变其行为 > - **模板方法模式**:在基类中定义算法骨架 > - **迭代器模式**:顺序访问聚合元素 > - **中介者模式**:定义封装对象交互方式的对象 > - **备忘录模式**:捕获和外部化对象内部状态 > - **责任链模式**:沿处理程序链传递请求 > - **访问者模式**:将算法与对象结构分离 ### 4. 架构模式 > 详见 [pattern-examples.md](./references/pattern-examples.md#架构模式示例) 了解下列架构模式的实现: > - **MVC**:分离关注点、用于 Web 应用、桌面应用 > - **MVVM**:将 UI 与业务逻辑分离、使用数据绑定 > - **整洁架构**:依赖规则、独立于框架、UI、数据库 > - **六边形架构**:应用核心与外部关注点隔离 > - **仓储模式**:在领域和数据映射层之间调解 > - **CQRS**:分离读写操作、提高可扩展性和性能 > - **事件溯源**:将状态存储为事件序列、提供审计跟踪 ### 5. 现代模式 > 详见 [pattern-examples.md](./references/pattern-examples.md#现代模式示例) 了解下列现代模式的实现: > - **依赖注入**:控制反转原则、从外部提供依赖项 > - **服务定位器**:用于获取服务的中央注册表 > - **空对象模式**:提供默认对象而不是 null > - **对象池模式**:重用创建成本高的对象 > - **断路器模式**:防止级联故障、快速失败 ## SOLID 原则 **单一职责原则(SRP)** - 一个类应该只有一个改变的理由 - 每个类做好一件事 **开闭原则(OCP)** - 对扩展开放,对修改关闭 - 使用抽象和多态 **里氏替换原则(LSP)** - 子类型必须可替换其基类型 - 派生类不得破坏基类契约 **接口隔离原则(ISP)** - 客户端不应依赖他们不使用的接口 - 创建特定接口而不是通用接口 **依赖倒置原则(DIP)** - 依赖于抽象,而不是具体实现 - 高层模块不应依赖于低层模块 ## 需要避免的反模式 **上帝对象(God Object)** - 类知道太多或做太多 - 违反 SRP **意大利面代码(Spaghetti Code)** - 纠缠的控制流 - 难以理解和维护 **熔岩流(Lava Flow)** - 永远不会删除的死代码 - 害怕破坏某些东西 **金锤子(Golden Hammer)** - 过度使用一种模式 - "当你有锤子时,一切看起来都像钉子" **过早优化(Premature Optimization)** - 在识别瓶颈之前进行优化 - 使代码不必要地复杂 **货物崇拜编程(Cargo Cult Programming)** - 在不理解原因的情况下使用模式 - 在没有理解的情况下复制代码 ## 模式选择指南 **何时使用创建型模式:** - 对象创建复杂 - 需要控制实例创建 - 想要将创建与使用解耦 **何时使用结构型模式:** - 需要组合对象 - 想要适配接口 - 需要简化复杂系统 **何时使用行为型模式:** - 需要定义对象之间的通信 - 想要封装算法 - 需要对象行为的灵活性 ## 示例 > 详见 [pattern-examples.md](./references/pattern-examples.md#实际示例) 了解下列实际实现示例: > - **示例 1**:重构为策略模式(从条件语句到策略对象) > - **示例 2**:实现仓储模式(领域实体、接口、具体实现) ## 最佳实践 - **首先理解问题** - 不要在不适合的地方强制使用模式。模式是解决反复出现问题的方案。 - **保持简单** - 从简单开始,根据需要添加模式。不要过度工程化。 - **清晰命名** - 适当时在类/方法名称中使用模式名称。使代码自文档化。 - **深思熟虑地组合模式** - 模式经常一起工作(工厂 + 单例、策略 + 模板方法等) - **考虑权衡** - 模式增加复杂性。平衡灵活性与简单性。 - **测试驱动开发** - 先写测试。模式自然地从重构中出现。 - **重构到模式** - 不要预先设计模式。让它们随着代码的发展而出现。 ## 代码审查清单 审查代码中模式使用时: - [ ] 该模式是否适合问题? - [ ] 实现是否正确? - [ ] 它是否提高了代码质量? - [ ] 它是否过度工程化? - [ ] 是否遵循 SOLID 原则? - [ ] 代码是否可测试? - [ ] 文档是否完善? - [ ] 是否有更简单的替代方案? ## 模式参考快速指南 | 问题 | 模式 | 何时使用 | |------|------|----------| | 需要单一实例 | 单例 | 全局状态、资源管理 | | 复杂对象创建 | 建造者 | 许多可选参数 | | 相关对象族 | 抽象工厂 | 需要一致的对象族 | | 克隆现有对象 | 原型 | 对象创建成本高 | | 接口不匹配 | 适配器 | 集成遗留代码 | | 添加职责 | 装饰器 | 需要灵活的扩展 | | 简化复杂系统 | 外观 | 需要简化接口 | | 控制访问 | 代理 | 延迟加载、访问控制 | | 可互换算法 | 策略 | 多个算法变体 | | 通知依赖者 | 观察者 | 事件处理、发布-订阅 | | 封装请求 | 命令 | 撤销/重做、排队操作 | | 状态依赖行为 | 状态 | 复杂状态转换 | ## 备注 设计模式是软件设计中常见问题的经过验证的解决方案。使用它们来: - 编写可维护、可扩展的代码 - 清晰地传达设计意图 - 利用软件社区的集体智慧 - 避免重新发明轮子 记住:**模式是工具,不是规则。** 使用判断力在特定上下文中适当地应用它们。最好的代码通常是有效解决问题的最简单的代码。