Photo by Lorem Ipsum
976 words
5 minutes
设计模式系列(六):实战认知
设计模式系列
Posts in this series (7)AI 智能总结
设计模式 6 实战认知
单纯熟记模式代码毫无意义,开发的核心是找准何时使用、何时拒绝、看懂框架如何巧妙运用模式。本节结合工程实战,搭配Spring、MyBatis、Go标准库实例。
一、各类模式适用场景 & 反例(什么时候不要用)
1. 创建型
单例 ✅适用:全局资源实例(连接池、配置管理器、日志工具) ❌反例:有状态对象;需要多套独立配置实例时,强行单例会引发数据错乱。
工厂方法/抽象工厂
✅适用:对象创建逻辑复杂、产品类型持续扩展、需要统一管控实例
❌反例:只存在一种产品、创建逻辑只有一行new,额外封装工厂纯属增加抽象层级。
建造者Builder ✅适用:实体参数繁多、大量可选参数、构建步骤固定 ❌反例:属性少于3个的简单POJO,没必要使用Builder。
2. 结构型
适配器 ✅适用:新旧系统对接、第三方接口数据格式兼容 ❌反例:接口本身易于改造,直接修改代码优于新增适配层。
装饰器 ✅适用:动态叠加功能,功能可以自由组合(IO流) ❌反例:功能固定、不需要动态增减,直接继承即可。
代理 ✅适用:访问控制、预处理、延迟加载、切面增强 ❌反例:无任何额外逻辑,仅仅转发方法,没必要引入代理。
外观模式(Facade) ✅适用:封装复杂子系统,对外提供简洁入口 ❌反例:子系统本身只有少量接口,封装门面属于多余。
3. 行为型
策略模式 ✅适用:大量if/else分支,后续算法持续扩充 ❌反例:分支固定、永远不会新增类型,if-else可读性更高。
模板方法 ✅适用:流程骨架固定,部分步骤可自定义拓展 ❌反例:流程随时可能大幅度改动,固定模板会限制拓展。
观察者 ✅适用:一对多事件通知,发布者与订阅者解耦 ❌反例:只有单一监听者,直接方法调用比事件模型更轻量。
二、主流框架源码里的设计模式案例
Spring
- 单例模式:Spring Bean默认单例池
- 工厂模式:BeanFactory、FactoryBean 负责对象创建
- 代理模式:AOP JDK动态代理 / CGLib代理
- 模板方法:JdbcTemplate、TransactionTemplate
- 外观模式:ApplicationContext,统一整合资源、Bean、环境配置
- 观察者:Spring事件驱动
ApplicationEvent
MyBatis
- 建造者模式:
SqlSessionFactoryBuilder构建会话工厂 - 工厂模式:SqlSessionFactory 创建 SqlSession
- 适配器模式:
LogAdapter适配不同日志框架(SLF4J/Log4j) - 装饰器模式:缓存模块
Cache多层装饰(刷新、阻塞、序列化缓存) - 代理模式:Mapper接口代理,动态生成Mapper实现
Golang 标准库
Go没有类,依靠结构体+隐式接口实现设计思想
- 装饰器:
io.Reader系列(bufio.Reader包装原始Reader) - 外观模式:
net/http封装底层TCP,对外提供简洁Handler接口 - 工厂模式:
http.NewServeMux创建路由处理器 - 策略模式:
crypto加密包,不同哈希算法实现统一Hash接口
三、实战核心认知总结
- 模式是解决方案,不是编码规范:先遇到问题,再选用模式;不要预先堆砌抽象。
- 框架使用模式的共性目标:解耦、预留扩展点、屏蔽底层复杂细节。
- 区分边界:小型业务优先简单实现;中长期迭代、存在多处扩展点再引入设计模式。
- 语言特性决定实现方式:Java偏向接口、继承;Go依靠组合、接口;Python依靠动态特性。
工程大忌:拿着模式模板硬套业务。优先遵循SOLID等基础原则,模式只是原则落地的工具。