设计模式实战:别背 23 种,先掌握这 6 个

举报
yd_237615889 发表于 2026/09/25 11:31:46 2026/09/25
【摘要】 博客 · 开发实践 / 代码设计 · 2026-09-25设计模式实战:别背 23 种,先掌握这 6 个设计模式不是背出来的知识点,而是「给常见问题起的名字」。真正高频的只有六七个——这篇按「痛点 → 形状 → 场景 → 误用」讲清它们,也讲清什么时候不该用。工程实践手记 ·2026-09-25 ·约 12 分钟阅读一、先立观念:模式是「问题的名字」GoF 二十三种设计模式,多数人的经历是:...
博客 · 开发实践 / 代码设计 · 2026-09-25

设计模式实战:别背 23 种,先掌握这 6 个

设计模式不是背出来的知识点,而是「给常见问题起的名字」。真正高频的只有六七个——这篇按「痛点 → 形状 → 场景 → 误用」讲清它们,也讲清什么时候不该用。


工程实践手记 ·2026-09-25 ·约 12 分钟阅读

一、先立观念:模式是「问题的名字」

GoF 二十三种设计模式,多数人的经历是:背了忘、忘了背,面试能说两句,写代码时一个都想不起来。问题不在记性,而在学习顺序——模式是从「反复出现的问题」里总结出来的名字,先有痛点,才有模式。反过来先背名字再找地方用,就是过度设计的起点。

模式真正的价值是沟通与识别:当你在一段代码里看到「每加一种类型就要改一次 switch」,能说出「这里是个策略问题」,比说「这里有点乱」有用得多。用之前先问三个问题:这里有没有稳定不变的变化点?同样的判断是否已经重复出现三次以上?抽象出来的收益是否大于它带来的间接层?三个都答"是",才值得引入模式。

模式不是目标,是解决特定问题的通用形状——先有痛点,再找模式。
· · ·

二、六个高频模式:按痛点对号入座

模式 解决什么问题 一句话形状 常见误用
策略 Strategy 分支随业务无限膨胀 把算法抽成可替换对象 只有一种实现也上策略
工厂 Factory 创建逻辑散落、依赖具体类型 集中创建,调用方只认接口 为「将来可能换」提前抽象
观察者 Observer 状态变化要通知多处 订阅发布,双向解耦 事件链路过长,难追踪
装饰器 Decorator 要给对象叠加增强 层层包装,顺序可控 包装层数失控,调试困难
适配器 Adapter 新旧接口不兼容、要隔离第三方 中间转换层 为核心代码自造外设接口
单例 Singleton 全局唯一资源 全局唯一入口 滥用成全局状态,难以测试

策略:把「越长越多的 if」变成可替换对象

痛点:每上线一种新的计费规则、折扣类型、审批流程,就要回到同一个函数里再加一个分支。形状:把每个分支抽成独立对象(或函数),用一张表或注册表把它们组织起来。

// 之前:分支会一直长
if (type === "vip") { ... }
else if (type === "coupon") { ... }

// 之后:规则是数据,新增不改旧代码
const DISCOUNTS = { vip: calcVip, coupon: calcCoupon };
const discount = (type, amount) => (DISCOUNTS[type] ?? identity)(amount);

装饰器:不改原类,叠加能力

痛点:同一个处理逻辑要按场景叠加日志、缓存、鉴权、限流,全都塞进原函数会变成一团乱麻。形状:把增强写成一层层的包装,每一层只做一件事、只关心顺序。**Web 框架的「中间件」就是装饰器思想最成功的落地**——顺序可插拔、职责单一切。

适配器:把第三方 SDK 挡在核心代码之外

痛点:支付、短信、对象存储各家 SDK 接口各不相同,核心业务里到处是某个厂商的专有类型——换供应商等于重写业务。形状:为核心代码定义一个自己的接口,再为每个厂商写一个适配器把调用转过去。**核心代码从此不依赖任何外部 SDK,换供应商只写一个新的适配器。**

· · ·

三、观察者、工厂、单例:三个「用对场景很香」的模式

  • 观察者:订单创建后要触发发券、通知、积分、埋点——直接串行调用会让订单逻辑依赖所有下游。改成发布一个事件、下游各自订阅,新增下游不动订单代码。注意:事件链路别拉太长,否则排查问题要跳五个文件
  • 工厂:当创建对象的逻辑开始散落(到处 new 具体类型、带一堆初始化参数),把创建收进一个地方。但要警惕「为将来可能换数据库而提前抽象」——没有第二种实现之前,工厂就是多余的一层
  • 单例:只有真正意义上「全局唯一」的资源才配得上它(进程级配置、连接池管理器)。它的本质是全局状态,会让测试互相污染、依赖关系隐形——能用依赖注入解决的,不要用单例

四、什么时候不该用:四种过度设计

  • 只有一个实现就上策略 / 工厂:多写三个文件换来"以后好扩展",而那个以后大概率不会来
  • 为扩展性提前抽象:结果每个需求都要改三层代码才能落地,抽象的间接成本立刻显现
  • 模式叠模式:工厂里套策略、策略里套观察者——读不懂的设计就是坏设计,跟用了多少模式无关
  • 单例随手用:测试无法隔离、并发下共享可变状态、依赖关系藏起来——出问题时最难查的就是它

五、什么时候该抽象了:三个信号

与其问"该用哪个模式",不如看信号:三次法则(同一段逻辑第三次出现,就该抽象);稳定变化点(同一处代码总是因为同一类需求被反复修改);具体类型判断散落(同一个 switch 判断在多处重复出现)。信号出现,模式的名字自然会浮现——这时候引入才是"解决问题",而不是"套模板"。

六、在代码评审里怎么谈模式

评审时别用模式当教条压人("你这没用工厂模式"),而是把问题命名出来、把选择权交给作者:「这里每加一种类型都要改这段,用一张策略表会不会更好读?」「这段直接 new 了第三方客户端,要不要加个适配器把它挡在核心之外?」——描述好处、给出选项,比宣布结论更容易被接受,也更符合"让代码更好"而不是"让代码按我的写法来"。

速查卡

你看到的现象 可以考虑的模式
一个函数的分支随业务无限增长 策略(把分支抽成可替换对象)
到处 new 具体类型、初始化逻辑散落 工厂(集中创建)
状态变化要通知很多下游 观察者(事件订阅)
同一条链路要按场景叠加增强 装饰器(中间件)
核心代码到处是第三方 SDK 类型 适配器(转换层)
需要进程内唯一资源 单例(优先改用依赖注入)

写在最后

设计模式最好的用法,是把它当成一套给坏味道命名的词汇表:看到重复的分支、散落的创建、失控的通知链,你能叫出问题的名字,也知道成熟的解法长什么样。至于用不用、用几个,永远由"这个具体问题"决定——先解问题,后提模式;宁少一层,不多一件。

下一步 · 找出你代码里最长的那段 switch
顺手做一次小练习:把它整理成一张策略表,看看是否更好读、新增是否更省事。系列下一篇候选:灰度发布策略、技术方案设计、HTTP/3 与网络基础。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。