如何选择设计模式:根据业务场景、变化点、复用性、可维护性进行综合评估

说实话,我见过太多人学设计模式时陷入一个怪圈——背了二十三种模式的类图,面试时对答如流,一到真实项目就懵了。为什么会这样?因为大家总在问「这个模式怎么用」,却很少问「我该不该用这个模式」。

今天我们就来聊聊这个核心问题。我个人习惯把选择设计模式比作「开药方」——你得先诊断病情,再对症下药。盲目套用模式,就像不管什么病都开阿莫西林,后果可想而知。

核心观点:设计模式的选择不是一道选择题,而是一道综合评估题。你需要从业务场景、变化点、复用性、可维护性四个维度去权衡。

一、先看业务场景:模式不是万能的

我在项目中遇到过这样一个场景:一个电商系统的订单处理流程,需要支持多种支付方式。当时团队里有人直接说「用策略模式啊」,然后就开干了。结果做到一半发现,支付方式之间其实有共享的逻辑(比如日志记录、异常处理),策略模式反而让代码变得支离破碎。

你看,这就是典型的「拿着锤子看什么都像钉子」。选择模式的第一步,不是翻书找模式,而是把业务场景拆清楚:

  • 这个场景的核心职责是什么?——是创建对象?是组织算法?还是协调多个对象?
  • 场景中有没有明显的「变」与「不变」?——变化点往往就是模式的切入点
  • 这个场景的生命周期有多长?——临时需求别上大炮打蚊子

举个例子,如果你只是做一个简单的日志工具,用单例模式就够了。但如果你要做一个支持多种输出格式(JSON、XML、纯文本)的日志系统,那策略模式或装饰器模式才值得考虑。

我的经验:先画一个简单的业务流程图,把「变」的部分圈出来。如果变化点超过3个,再考虑用模式;如果只有1个变化点,一个if-else可能更清晰。

二、识别变化点:模式是为「变化」服务的

设计模式的本质,说白了就是「封装变化」。你想想看,GoF的二十三种模式,哪一个不是在解决「某部分容易变化」的问题?

我习惯把变化点分为三类:

变化类型 典型场景 推荐模式
算法/行为变化 支付方式、排序算法、促销策略 策略模式、模板方法模式
对象创建变化 不同数据库连接、不同UI组件 工厂模式、建造者模式
对象交互变化 事件通知、消息推送、状态流转 观察者模式、状态模式

这里有个坑,我曾经踩过——过度封装变化。有一次我接手一个报表系统,发现里面用了三层抽象工厂,就为了支持两种数据库。结果代码读起来像俄罗斯套娃,改一个字段要动四个文件。嗯,后来我重构时发现,其实用简单的工厂方法加配置就能搞定。

避坑指南:我曾经因为过度设计,把一个只需要支持MySQL的系统硬生生做成了「支持所有数据库」的架构。结果项目交付后两年,其他数据库一个都没用上。记住:只为当前已知的变化做设计,不要为想象中的变化买单。

三、评估复用性:别为了复用而复用

复用性是个好东西,但也是个陷阱。我见过太多人为了「复用」而引入设计模式,结果代码的耦合度反而更高了。

怎么评估复用性?我一般问自己三个问题:

  1. 这段代码会被几个地方调用?——如果只有一处调用,别急着抽象
  2. 调用方对这段代码的期望是否一致?——如果每个调用方都想要不同的行为,强行复用反而坏事
  3. 复用的代价是什么?——引入接口、抽象类、工厂,这些都会增加理解成本

举个例子,你写了一个数据导出功能,目前只支持导出Excel。如果未来大概率要支持PDF和CSV,那用策略模式封装导出算法是合理的。但如果这个导出功能只有这一个场景在用,而且未来半年都没有扩展计划,那一个简单的方法就够了。

我的原则:复用性不是越高越好,而是「恰到好处」。我宁愿写两段相似的代码,也不愿引入一个让团队所有人都看不懂的抽象层。

四、权衡可维护性:模式是工具,不是目的

可维护性,说白了就是「未来的人改代码时会不会骂娘」。设计模式能提升可维护性,但前提是——团队里的人都懂这个模式

我记得有一次做代码评审,看到有人用责任链模式处理一个只有三个步骤的校验流程。代码写得确实漂亮,每个处理器都遵循了单一职责。但问题是,团队里一半的人看不懂责任链模式,每次改需求都要拉着原作者问半天。你说这算可维护性好还是不好?

所以,评估可维护性时,我建议考虑以下几点:

  • 团队的技术水平——如果团队普遍对设计模式不熟,优先选择简单直观的模式(如策略模式、工厂方法),少用复杂的模式(如访问者模式、解释器模式)
  • 代码的可读性——模式引入后,代码是变清晰了还是变绕了?如果绕了,说明选错了
  • 修改的便利性——当需求变化时,改一处代码就能搞定,还是需要改多处?

一个小技巧:写完代码后,假装自己是三个月后的自己,重新读一遍。如果读不懂,说明可维护性有问题。

五、综合评估框架:一张图说清楚

说了这么多,我们来总结一下。我平时做模式选择时,会画这样一张决策图:

设计模式选择决策框架 业务需求 ① 业务场景 ② 变化点 ③ 复用性 ④ 可维护性 核心职责是什么? 变与不变在哪里? 生命周期多长? 算法/行为变化? 对象创建变化? 对象交互变化? 被几处调用? 调用方期望一致? 复用代价多大? 团队技术水平? 代码可读性? 修改便利性? 综合评估 → 选择最合适的模式

这张图的核心逻辑是:从业务需求出发,依次评估四个维度。每个维度都有对应的子问题,回答完这些问题后,你自然就知道该用哪个模式了。

六、实战案例:一个订单系统的模式选择

最后,我们来看一个完整的案例。假设你要设计一个订单系统,支持以下功能:

  • 普通订单、团购订单、秒杀订单三种类型
  • 每种订单的创建流程不同,但都有校验、计算价格、生成订单三个步骤
  • 未来可能增加新的订单类型(如拼团订单)

我们按四个维度来评估:

评估维度 分析结果 模式建议
业务场景 核心是「订单创建」,不同订单类型有共同步骤也有差异 模板方法模式(固定步骤)+ 策略模式(差异部分)
变化点 订单类型会新增,但创建流程的骨架不变 模板方法模式封装骨架,子类实现差异
复用性 校验、价格计算等逻辑会被多个订单类型复用 策略模式封装可复用的算法
可维护性 团队熟悉模板方法和策略模式,代码结构清晰 两种模式结合,新增订单类型只需新增子类

最终,我选择了模板方法模式 + 策略模式的组合。模板方法定义订单创建的骨架,策略模式处理价格计算等可变算法。这样既保证了复用性,又让新增订单类型变得非常简单。

总结一下:选择设计模式没有标准答案,但有标准方法。从业务场景出发,识别变化点,评估复用性,权衡可维护性——把这四步走完,你的选择就不会太离谱。

记住,设计模式是工具,不是目的。用对了,代码如诗;用错了,代码如屎。嗯,这话糙理不糙。

公众号:蓝海资料掘金营,微信deep3321