976 words
5 minutes
设计模式系列(六):实战认知

AI 智能总结

设计模式 6 实战认知#

单纯熟记模式代码毫无意义,开发的核心是找准何时使用、何时拒绝、看懂框架如何巧妙运用模式。本节结合工程实战,搭配Spring、MyBatis、Go标准库实例。

一、各类模式适用场景 & 反例(什么时候不要用)#

1. 创建型#

单例 ✅适用:全局资源实例(连接池、配置管理器、日志工具) ❌反例:有状态对象;需要多套独立配置实例时,强行单例会引发数据错乱。

工厂方法/抽象工厂 ✅适用:对象创建逻辑复杂、产品类型持续扩展、需要统一管控实例 ❌反例:只存在一种产品、创建逻辑只有一行new,额外封装工厂纯属增加抽象层级。

建造者Builder ✅适用:实体参数繁多、大量可选参数、构建步骤固定 ❌反例:属性少于3个的简单POJO,没必要使用Builder。

2. 结构型#

适配器 ✅适用:新旧系统对接、第三方接口数据格式兼容 ❌反例:接口本身易于改造,直接修改代码优于新增适配层。

装饰器 ✅适用:动态叠加功能,功能可以自由组合(IO流) ❌反例:功能固定、不需要动态增减,直接继承即可。

代理 ✅适用:访问控制、预处理、延迟加载、切面增强 ❌反例:无任何额外逻辑,仅仅转发方法,没必要引入代理。

外观模式(Facade) ✅适用:封装复杂子系统,对外提供简洁入口 ❌反例:子系统本身只有少量接口,封装门面属于多余。

3. 行为型#

策略模式 ✅适用:大量if/else分支,后续算法持续扩充 ❌反例:分支固定、永远不会新增类型,if-else可读性更高。

模板方法 ✅适用:流程骨架固定,部分步骤可自定义拓展 ❌反例:流程随时可能大幅度改动,固定模板会限制拓展。

观察者 ✅适用:一对多事件通知,发布者与订阅者解耦 ❌反例:只有单一监听者,直接方法调用比事件模型更轻量。

二、主流框架源码里的设计模式案例#

Spring#

  1. 单例模式:Spring Bean默认单例池
  2. 工厂模式:BeanFactory、FactoryBean 负责对象创建
  3. 代理模式:AOP JDK动态代理 / CGLib代理
  4. 模板方法:JdbcTemplate、TransactionTemplate
  5. 外观模式:ApplicationContext,统一整合资源、Bean、环境配置
  6. 观察者:Spring事件驱动 ApplicationEvent

MyBatis#

  1. 建造者模式:SqlSessionFactoryBuilder 构建会话工厂
  2. 工厂模式:SqlSessionFactory 创建 SqlSession
  3. 适配器模式:LogAdapter 适配不同日志框架(SLF4J/Log4j)
  4. 装饰器模式:缓存模块 Cache 多层装饰(刷新、阻塞、序列化缓存)
  5. 代理模式:Mapper接口代理,动态生成Mapper实现

Golang 标准库#

Go没有类,依靠结构体+隐式接口实现设计思想

  1. 装饰器:io.Reader 系列(bufio.Reader 包装原始Reader)
  2. 外观模式:net/http 封装底层TCP,对外提供简洁Handler接口
  3. 工厂模式:http.NewServeMux 创建路由处理器
  4. 策略模式:crypto 加密包,不同哈希算法实现统一Hash接口

三、实战核心认知总结#

  1. 模式是解决方案,不是编码规范:先遇到问题,再选用模式;不要预先堆砌抽象。
  2. 框架使用模式的共性目标:解耦、预留扩展点、屏蔽底层复杂细节。
  3. 区分边界:小型业务优先简单实现;中长期迭代、存在多处扩展点再引入设计模式。
  4. 语言特性决定实现方式:Java偏向接口、继承;Go依靠组合、接口;Python依靠动态特性。

工程大忌:拿着模式模板硬套业务。优先遵循SOLID等基础原则,模式只是原则落地的工具。

设计模式系列(六):实战认知
https://fuwari.vercel.app/posts/design-series/design-06-practice/
Author
Zero02
Published at
2025-08-05
License
CC BY-NC-SA 4.0