学了设计模式,却不知道怎么选择?

本人主要讲述设计模式怎么去选择,这仅仅是不知从何下手提供一个抓手的东西,并不是银弹。常想、多用,积累经验后,方可灵活运用,做到无模式胜有模式,才可能会在复杂场景中,设计出高质量的系统。

设计模式的选择是一个从问题到解决方案的递进过程。通过明确问题类型、分析目标特性、遵循设计原则以及结合场景需求,可以高效地筛选出最佳设计模式,从而达到优化系统设计,提升代码质量和可维护性。设计模式不仅是一种工具,更是一种面向对象程序设计的思维方式,能帮助开发者构建更加稳定和易于维护的软件系统。

这篇文章花了挺多时间去整理的,还请耐心看完。

先说整体上,怎么考虑,怎么选择。

1.设计模式选择的综合指南

1.1. 核心决策框架

  1. 问题驱动分类法

将系统问题归类为三大场景,形成决策起点:

  • 创建型问题 :对象如何诞生?(如电商购物车实例的全局唯一性 → 单例模式
  • 结构型问题 :对象如何组织?(如动态扩展订单附加服务 → 装饰者模式
  • 行为型问题 :对象如何协作?(如用户操作触发多模块联动 → 观察者模式
  1. 原则约束检查表
    选择模式时需通过设计原则验证:
  • 单一职责:该模式是否让每个类/模块更专注?(如状态模式分离状态逻辑与主业务)
  • 开闭原则:新增功能是否无需修改既有代码?(如装饰者模式叠加功能不破坏原有结构)
  • 依赖倒置:是否通过接口而非具体实现交互?(如抽象工厂模式隔离具体产品类)
  • 里氏替换原则:具体实现类的切换是否影响程序正常使用?(如策略模式支持动态切换具体实现类)

1.2. 模式选择进阶策略

  1. 模式组合技
  • 动态创建+行为扩展 :工厂方法+策略模式
    (示例:支付系统中,工厂创建支付处理器,策略模式切换算法)
  • 状态管理+消息通知 :状态模式+观察者模式
    (示例:订单状态变更时,自动触发库存更新和用户通知)
  1. 反模式预警

强调设计模式中设计思想的运用

陷阱 后果 解决方案
单例滥用 测试困难、隐藏依赖 依赖注入+工厂模式(如Spring框架)
过度装饰者嵌套 调试链路复杂 合理控制层级,结合组合模式
观察者内存泄漏 未及时取消订阅 弱引用+生命周期管理
  1. 性能权衡指南
  • 空间换时间:享元模式共享对象减少内存重复--如游戏中的树木渲染共享纹理
  • 时间换灵活:代理模式增加间接层带来性能损耗--需评估延迟是否在可接受范围
  • 模式轻量化:函数式替代方案--如Lambda替代策略模式接口

2. 设计模式决策树(23种)

细致到每个设计模式的特点,通过问题类型和场景特征,逐步定位适合的设计模式:

2.1. 第一步:确定核心问题类型

这个前面也已经提到过的了。

  1. 是否需要创建/管理对象?→ 创建型模式(6种)
  2. 是否需要组织对象结构? → 结构型模式(7种)
  3. 是否需要定义对象间协作?→ 行为型模式(11种)

2.2. 第二步:细化选择路径

1. 创建型模式(5种)

问题:如何高效、灵活地创建对象?

plaintext 复制代码
是否需要控制对象实例数量和提供全局访问点?
├─ 是 → 单例模式(Singleton)
└─ 否 → 
   是否需要分步构造复杂对象?
   ├─ 是 → 建造者模式(Builder)
   └─ 否 → 
      是否通过克隆快速创建对象(避免高成本构造)?
      ├─ 是 → 原型模式(Prototype)
      └─ 否 → 
         是否需要在不暴露具体类的前提下,动态选择实例化的类?
         ├─ 是 → 工厂方法模式(Factory Method)
         └─ 否 →
            是否需要创建一组相关对象,并确保它们协同工作?
            ├─ 是 → 工厂方法模式(Factory Method)
            └─ 否 → 简单工厂 或 直接创建

2. 结构型模式(7种)

问题:如何优化对象之间的组合与关系?

plaintext 复制代码
是否需要扩展对象功能且不影响现有代码?
├─ 是 → 
   │ 是否需动态叠加功能?
   │ ├─ 是 → 装饰者模式(Decorator)
   │ └─ 否 → 适配器模式(Adapter)
└─ 否 → 
   是否需要简化复杂子系统?
   ├─ 是 → 外观模式(Facade)
   └─ 否 → 
      是否需要解耦抽象与实现,以支持独立变化?
      ├─ 是 → 桥接模式(Bridge)
      └─ 否 → 
         是否需要共享大量对象以减少内存资源?
         ├─ 是 → 享元模式(Flyweight)
         └─ 否 → 
            是否需要组合对象为树形结构("部分-整体"的层次关系)?
            ├─ 是 → 组合模式(Composite)
            └─ 否 → 
               是否需要代理控制访问或优化性能?
               ├─ 是 → 代理模式(Proxy)
               └─ 否 → 

3. 行为型模式(11种)

问题:如何管理对象间的协作与责任分配?

plaintext 复制代码
是否需要动态切换一组算法?
├─ 是 → 策略模式(Strategy)
└─ 否 → 
   是否通过状态驱动行为?
   ├─ 是 → 状态模式(State)
   └─ 否 → 
      是否需要集中管理对象间复杂交互?
      ├─ 是 → 中介者模式(Mediator)
      └─ 否 → 
         是否需要支持请求的撤销/重做?
         ├─ 是 → 备忘录模式(Memento)
         └─ 否 → 
            是否需要将请求封装为对象(支持参数化、队列化)?
            ├─ 是 → 命令模式(Command)
            └─ 否 → 
               是否需要被观察的对象变化后,会自动通知多个订阅者?
               ├─ 是 → 观察者模式(Observer)
               └─ 否 → 
                  是否需要由多个对象依次处理请求?
                  ├─ 是 → 责任链模式(Chain of Responsibility)
                  └─ 否 → 
                     是否需要定义操作步骤/算法骨架,并允许子类重写具体细节?
                     ├─ 是 → 模板方法模式(Template Method)
                     └─ 否 → 
                        是否需要遍历集合对象?
                        ├─ 是 → 迭代器模式(Iterator)
                        └─ 否 → 
                           是否需要分离数据结构和操作行为?
                           ├─ 是 → 访问者模式(Visitor)
                           └─ 否 → 
                              是否需要解释和处理某种语言或表达式的语法规则?
                              ├─ 是 → 解释器模式(Interpreter)
                              └─ 否 → 

注:行为型模式的选择并无严谨的先后顺序。

2.3. 决策树使用建议

设计模式决策树的核心逻辑是:

问题分类目标匹配原则验证

在实际开发中需结合具体场景灵活调整,最终目标是写出高内聚、低耦合、可重用、易扩展易维护高性能的代码。 通过刻意练习(如重构既有代码、阅读框架源码),可逐步培养模式选择的直觉。

避免教条主义:模式是工具而非规则,例如简单场景无需强制使用设计模式,而复杂场景需要多种模式相互配合和模式创新。

3. 总结

设计模式的选择如同烹饪调味------需要根据食材特性 (系统需求)、食客口味 (团队能力)、厨房条件(技术栈)综合决策。关键在于:

  1. 保持问题敏感度:从代码异味(如巨型类、扩散式修改)中发现模式应用契机
  2. 掌握模式本质:理解模式背后的抽象原则而非具体实现
  3. 培养架构直觉:通过阅读优秀源码(如Spring、Netty)积累模式使用经验

最终目标不是成为模式的奴隶,而是让模式成为手中游刃有余的设计语言 ,构建出兼具弹性简洁性的软件系统。

通过项目开发,积累经验后,你会逐渐能根据项目的具体需求,灵活运用合适的设计模式。

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。
后续会分享

秘籍1>>掌握设计模式:23种经典模式实践、选择、价值与思想.pdf

秘籍2>>设计模式实战项目:markdown文本编辑器软件开发(开放所有源代码


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享