首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
设计模式复习实战指南:从七大原则到重点模式代码落地
📅 2026/10/24 15:00:23
✍️ 爱科研究院
👁 阅读 3,247
简介这份《大话设计模式复习》文档面向具备一定面向对象编程基础、工作1至3年的研发人员系统梳理设计模式的核心知识体系。内容从设计模式的定义、分类、特点与应用场景切入详细讲解单一职责、开放-封闭、依赖倒转、里氏代换、迪米特法则、合成/聚合及接口隔离七大设计原则并深入剖析抽象工厂、策略、外观、适配器、组合、单例、中介者七种常用模式以及其余十五种模式每种均配以定义、UML类图、基础代码与实例。文档还横向对比不同模式的差异总结模式选择的关键维度并附练习题与模拟试卷辅助巩固。资源包为单个docx文件约3.66MB结构完整、目录清晰便于按章节检索学习。目前已有191人学习适合希望提升代码可维护性、可扩展性与复用能力并在实际项目中灵活选用设计模式的开发者参考。1. 从一次代码评审翻车说起为什么设计模式复习不能只背 23 个名字去年帮一个做企业级管理系统的团队看代码需求是加一种新的支付渠道。按理说这是个小改动结果开发同学在PaymentService里又塞了一个else if那个类已经膨胀到 1800 多行改完之后回归测试直接炸了三个老渠道。问题不在他不会写代码而在于他脑子里没有「策略模式」这个可替换的抽象层——所有渠道逻辑硬编码在一个类里扩展一次就动一次核心逻辑开放-封闭原则形同虚设。这就是设计模式复习这件事最尴尬的地方很多人能背出 23 个模式的名字和分类但真到项目里该用的时候想不起来或者用错了地方。这份《大话设计模式复习》文档的价值恰恰在于它不是干巴巴地列定义而是把七大设计原则、七大重点模式抽象工厂、策略、外观、适配器、组合、单例、中介者和剩余 15 种模式全部配了 UML 类图、基础代码和真实实例最后还做了易混淆模式的横向对比和模拟试卷。它适合两类人一是工作 1-3 年、想从「能写功能」进阶到「能设计结构」的开发者二是正在准备软件工程方向课程设计或毕设答辩、需要一套完整模式应用综述来支撑方案的同学。下面我按「需求怎么立 → 结构怎么设计 → 代码怎么落地 → 怎么验收」这条线把这份复习资料拆成一份可以直接照着走的方案。2. 需求与技术选型先想清楚复习设计模式到底要解决什么问题2.1 复习目标不是记住 23 个名字而是建立「问题→模式」的映射大多数人复习设计模式的失败路径是这样的打开文档从「单例模式」开始看看到「访问者模式」已经忘了前面一半合上文档脑子里只剩「好像有个工厂」。根本原因是把设计模式当成了知识点来背而不是当成工具箱来用。正确的复习目标应该反过来定先明确你手头有哪些典型问题场景再倒推该用哪个模式。比如「对象创建逻辑复杂且需要解耦」对应工厂系列「算法需要运行时切换」对应策略模式「子系统接口太复杂需要简化」对应外观模式「不兼容接口需要转换」对应适配器模式。这份文档里七大重点模式之所以被单独拎出来分析就是因为它们在真实项目中的出现频率最高抽象工厂管对象族创建、策略管算法互换、外观管接口简化、适配器管接口转换、组合管树形结构、单例管全局唯一、中介者管多对象解耦——每一个都对应一类反复出现的工程问题。所以复习的第一件事是给自己列一张「我最近写过的代码里哪些地方改起来最痛苦」的清单然后带着这些问题去对照模式。这比从头背到尾效率高得多。2.2 技术栈与文档结构Java 为主、C 补充UML 贯穿始终这份复习资料的技术选型很明确主体代码用 Java 实现抽象工厂和策略模式的实例部分有 C 版本作为对照。这个选择是合理的因为 Java 的接口和抽象类机制天然适合演示面向对象的设计模式而 C 的多态和虚函数则能帮你理解模式在更底层语言里的形态差异。文档的整体结构分四层层次内容作用基础层设计模式定义、分类、特点、应用场景、UML 类图规范建立统一术语和表达方式原则层七大设计原则SRP、OCP、DIP、LSP、LOD、CARP、ISP提供评判设计好坏的标准重点模式层抽象工厂、策略、外观、适配器、组合、单例、中介者高频模式深度剖析含完整代码扩展与对比层剩余 15 种模式 易混淆模式对比 练习题与模拟试卷补齐知识面强化辨析能力这个结构的聪明之处在于先用原则建立判断标准再用重点模式打透几个典型场景最后用对比表把容易混淆的模式区分开。复习的时候如果时间紧可以按「原则 → 七大模式 → 对比表 → 模拟试卷」的顺序走把剩余 15 种模式作为查阅手册而不是精读材料。2.3 适用人群与前置知识会写类不等于会做设计这份资料明确说了适合「具备一定编程基础、对面向对象设计有了解」的研发人员。翻译一下就是你得能看懂 Java 的 interface、abstract class、继承和多态知道什么是 UML 类图中的泛化、实现、关联、聚合、组合关系。如果这些还不熟直接看模式代码会很吃力。具体来说前置知识包括三块一是面向对象三大特性封装、继承、多态的实际运用经验不是概念背诵二是 UML 类图的基本读图能力至少能分清实线空心三角是继承、虚线空心三角是实现三是至少写过 3000 行以上的项目代码否则你很难体会到「这个类改起来真痛苦」是什么感觉也就无法理解模式要解决的真实痛点。提示如果你目前只写过课程作业级别的小程序建议先找一个开源项目读一读它的分层结构再回来复习模式效果会好很多。3. 总体设计七大原则打底、三类模式分层、对比表收口的复习框架3.1 七大设计原则是判断模式用得好不好的标尺文档把七大原则放在模式分析之前这个顺序不能颠倒。因为设计模式是「术」设计原则是「道」——你不知道什么是好的设计就没法判断一个模式用得对不对。七大原则里最核心的是三条开放-封闭原则OCP要求软件实体对扩展开放、对修改关闭这是所有模式追求的终极目标依赖倒转原则DIP要求高层模块和低层模块都依赖抽象这是实现 OCP 的主要手段单一职责原则SRP要求一个类只有一个引起变化的原因这是控制类膨胀的第一道防线。剩下四条各有侧重里氏代换原则LSP保证子类能替换父类而不破坏行为契约迪米特法则LOD要求对象之间尽量少直接通信、通过中间人转发合成/聚合原则CARP优先用组合而非继承来降低耦合接口隔离原则ISP要求把大接口拆成小接口避免依赖不需要的方法。复习的时候我建议这样用每看完一个模式回头对照它「应用了哪些原则、违反了哪些原则」。比如文档里抽象工厂模式的分析就明确写了——它应用了依赖倒转原则和合成/聚合原则但在新增产品等级结构时会违反开放-封闭原则。这种「有得有失」的分析才是真正理解模式的关键而不是简单地说「这个模式好」。3.2 三类模式的分层逻辑创建型管怎么生、结构型管怎么拼、行为型管怎么动23 种设计模式按目的分为三大类这个分类不是随便分的它对应了软件设计中三个最基本的问题维度创建型模式5 种解决的是「对象怎么创建」的问题。单例模式保证全局唯一实例工厂方法模式把创建延迟到子类抽象工厂模式创建整个产品族建造者模式分步构建复杂对象原型模式通过克隆创建新对象。它们的共同目标是把对象的创建和使用分离让客户端不依赖具体类。结构型模式7 种解决的是「类和对象怎么组合」的问题。适配器模式转换接口装饰器模式动态添加职责代理模式控制访问外观模式简化子系统接口桥接模式分离抽象与实现组合模式处理树形结构享元模式共享细粒度对象。它们的共同目标是通过组合关系构建更灵活的结构。行为型模式10 种解决的是「对象之间怎么交互和分配职责」的问题。策略模式封装可互换算法观察者模式建立一对多依赖通知命令模式把请求封装为对象状态模式让对象在内部状态改变时改变行为责任链模式沿链传递请求模板方法模式定义算法骨架迭代器模式顺序访问集合元素中介者模式集中管理对象间交互备忘录模式捕获和恢复状态访问者模式在不改变元素类的前提下定义新操作。复习时按这个分层走每类先抓 2-3 个最常用的模式吃透再扩展到同类其他模式比按字母顺序或难度顺序背要高效得多。3.3 对比表是复习收口的关键工具文档最后一部分的对比表是我认为最有价值的内容之一。它把容易混淆的模式成对或成组地放在一起比较简单工厂 vs 工厂方法 vs 抽象工厂从「一个工厂类管所有产品」到「一个工厂接口管一类产品」再到「一个工厂接口管一族产品」抽象层级逐步提升适配器 vs 装饰器 vs 代理三者都涉及「包装」一个对象但适配器改变接口、装饰器增强功能、代理控制访问策略 vs 状态两者都通过组合持有可变行为但策略是客户端主动选择算法状态是对象内部状态变化驱动行为切换观察者 vs 中介者观察者是一对多的广播通知中介者是多对多的集中协调责任链 vs 中介者责任链是请求沿链传递直到被处理中介者是所有交互都经过中心节点这些对比不是让你背结论而是让你在选型时能快速排除不合适的选项。比如你面对一个「需要动态切换算法」的场景看到「策略 vs 状态」的对比就知道如果切换是客户端主动发起的选策略如果是对象内部状态变化触发的选状态。4. 核心模块实现从抽象工厂到中介者的代码落地与设计说明4.1 抽象工厂模式可移植数据访问层的完整实现抽象工厂是文档里篇幅最长的模式分析因为它涉及的产品族概念最复杂。文档给的实例是「可移植数据访问程序」——同一套业务逻辑需要支持 SQL Server 和 Access 两种数据库每种数据库都要创建 User 和 Department 两类对象。先看抽象工厂接口和具体工厂的定义// 抽象工厂接口声明创建产品族的方法 public interface IFactory { IUser CreateUser(); // 创建 User 对象的接口 IDepartment CreateDepartment(); // 创建 Department 对象的接口 } // SQL Server 具体工厂创建 SQL Server 产品族 public class SqlServerFactory implements IFactory { public IUser CreateUser() { return new SqlserverUser(); // 返回 SQL Server 的 User 实现 } public IDepartment CreateDepartment() { return new SqlserverDepartment(); } } // Access 具体工厂创建 Access 产品族 public class AccessFactory implements IFactory { public IUser CreateUser() { return new AccessUser(); } public IDepartment CreateDepartment() { return new AccessDepartment(); } }这段代码的关键设计点在于客户端只依赖IFactory、IUser、IDepartment三个抽象完全不感知具体用的是哪个数据库。切换数据库时只需要换一个工厂实例业务代码一行不用改。// 客户端代码只依赖抽象接口 public class Client { public static void main(String[] args) { // 切换数据库只需改这一行 IFactory factory new SqlServerFactory(); // IFactory factory new AccessFactory(); IUser iu factory.CreateUser(); iu.Insert(new User()); iu.GetUser(1); IDepartment id factory.CreateDepartment(); id.Insert(new Department()); id.GetDepartment(1); } }参数说明IFactory是抽象工厂接口SqlServerFactory和AccessFactory是具体工厂IUser和IDepartment是抽象产品接口SqlserverUser、AccessUser、SqlserverDepartment、AccessDepartment是具体产品。客户端通过工厂接口获取产品通过产品接口调用业务方法。这个模式的优缺点文档写得很清楚优点是分离接口和实现、客户端与具体产品解耦、增加产品族时符合依赖倒转原则缺点是增加新的产品等级结构比如再加一个IScore接口时需要修改抽象工厂和所有具体工厂违反开放-封闭原则。所以抽象工厂适合「产品族稳定、产品等级结构可能扩展」的场景反过来就要慎重。4.2 策略模式商场收银系统的算法互换设计策略模式解决的是「算法需要运行时切换」的问题。文档用的实例是商场收银系统不同折扣策略对应不同的收费算法。// 策略接口声明算法方法 interface Strategy { void doAlgorithm(); } // 具体策略 A class StrategyA implements Strategy { public void doAlgorithm() { // 算法 A 的具体实现 } } // 上下文持有策略对象委托执行 class Context { private Strategy strategy; // 运行时注入具体策略 public void setStrategy(Strategy s) { strategy s; } public void executeStrategy() { strategy.doAlgorithm(); // 委托给具体策略执行 } }设计说明Context类是整个模式的核心它持有一个Strategy接口的引用但不关心具体是哪个实现。客户端通过setStrategy()方法在运行时注入不同的策略对象然后统一调用executeStrategy()。这样新增一种折扣算法只需要实现一个新的Strategy子类不需要修改Context和已有策略类完全符合开放-封闭原则。文档还给了 C 版本的收银系统实现核心思路一致只是用虚函数替代了 Java 的接口。对比看两种语言的实现能帮你理解策略模式的本质不管语言怎么变「定义算法族 → 封装每个算法 → 使它们可互换」这个结构是不变的。策略模式应用的设计原则包括开放-封闭原则新增策略不改已有代码、依赖倒转原则Context 依赖 Strategy 抽象而非具体策略、合成/聚合原则Context 通过组合持有 Strategy 而非继承。它和状态模式的区别在于策略模式的切换由客户端主动发起状态模式的切换由对象内部状态变化驱动。4.3 单例模式与中介者模式全局唯一与多对多解耦单例模式是文档里篇幅较长的另一个模式因为它的实现方式有多种饿汉式、懒汉式、双重检查锁、静态内部类、枚举每种都有线程安全和性能上的取舍。核心目标只有一个保证一个类只有一个实例并提供一个全局访问点。// 双重检查锁实现兼顾线程安全和延迟加载 public class Singleton { // volatile 禁止指令重排序防止拿到未初始化完的对象 private static volatile Singleton instance; private Singleton() {} // 私有构造禁止外部 new public static Singleton getInstance() { if (instance null) { // 第一次检查避免不必要的同步 synchronized (Singleton.class) { if (instance null) { // 第二次检查确保只创建一次 instance new Singleton(); } } } return instance; } }参数说明volatile关键字是必须的它禁止 JVM 指令重排序防止在instance new Singleton()这行代码中对象还没初始化完成就把引用赋值给instance导致其他线程拿到一个半成品对象。这是单例模式最容易翻车的地方也是面试高频考点。中介者模式解决的是「多个对象之间交互复杂、耦合严重」的问题。文档里的定义是用一个中介对象来封装一系列的对象交互使各对象不需要显式地相互引用。同事类之间不直接通信全部通过中介者转发。// 抽象中介者 abstract class Mediator { public abstract void send(String message, Colleague colleague); } // 抽象同事类 abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator mediator; } } // 具体同事类 A class ConcreteColleagueA extends Colleague { public ConcreteColleagueA(Mediator mediator) { super(mediator); } public void send(String message) { mediator.send(message, this); // 通过中介者转发 } public void notify(String message) { // 接收来自中介者的通知 } }设计说明中介者模式把多对多的网状依赖变成了一对多的星形依赖同事类之间不再直接引用所有交互都经过中介者。这符合迪米特法则——两个类若不必直接通信就不发生直接作用。代价是中介者本身可能变得很复杂如果同事类太多、交互逻辑太杂中介者会膨胀成一个「上帝类」。所以中介者模式适合交互规则明确且相对稳定的场景不适合交互逻辑频繁变化的场景。5. 避坑与常见问题复习设计模式最容易翻车的五个点5.1 把模式当模板硬套为了用而用现象项目里明明只有一个数据库、一种支付方式却非要上抽象工厂和策略模式代码量翻了三倍维护的人一脸懵。原因把「用了多少模式」当成了设计能力的体现忽略了模式是用来解决特定问题的工具不是目的。解决每次想引入一个模式之前先问自己三个问题——不用这个模式会怎样未来真的会有多种实现吗引入后代码是更简单还是更复杂了如果答案是「不用也能跑」「短期内不会扩展」「引入后更复杂」那就先别用。模式是等到痛点出现时才上的不是提前铺路的。5.2 混淆策略模式和状态模式现象写了一个策略模式但策略的切换逻辑写在 Context 内部根据某个字段值自动切换结果和状态模式长得一模一样自己都说不清用的是哪个。原因两个模式的类图结构几乎相同都是 Context 持有抽象接口接口有多个实现区别只在「谁驱动切换」和「切换的语义」。解决记住一条判断标准——如果切换是客户端主动选择的比如用户选了「打八折」用策略模式如果切换是对象内部状态变化自动触发的比如订单从「待支付」变成「已支付」后行为自动改变用状态模式。策略模式的 Context 通常提供setStrategy()方法供外部调用状态模式的 Context 通常内部管理状态转换。5.3 单例模式忘记处理线程安全现象本地测试一切正常上线后偶尔出现两个单例实例导致配置不一致或资源重复初始化。原因用了懒汉式但没有加锁或者加了锁但没加volatile多线程环境下指令重排序导致拿到未初始化完的对象。解决如果对延迟加载没有硬性要求直接用饿汉式类加载时就创建实例JVM 保证线程安全如果需要延迟加载用双重检查锁加volatile或者用静态内部类方式利用 JVM 的类加载机制保证线程安全且实现延迟加载。最省事的是枚举单例天然线程安全且防止反射攻击。5.4 抽象工厂新增产品等级结构时大面积改代码现象原本只支持 User 和 Department 两类对象的数据库访问层现在要加一个 Score 对象结果抽象工厂接口、两个具体工厂类、所有相关代码都要改。原因抽象工厂模式的设计目标是「增加产品族容易增加产品等级结构困难」。产品族是横向的SQL Server 族、Access 族产品等级结构是纵向的User、Department、Score。纵向扩展必然要改工厂接口。解决如果产品等级结构经常变化抽象工厂不是好选择可以考虑用简单工厂配合反射或者改用工厂方法模式。如果产品等级结构稳定、产品族可能扩展抽象工厂才是合适的。选型前先判断哪个维度更可能变化。5.5 外观模式把不该简化的接口也简化了现象为了「让调用方便」写了一个外观类把子系统所有接口都包了一层结果子系统新增功能时外观类也要跟着改而且有些调用方需要精细控制子系统外观类反而成了障碍。原因外观模式的定位是「为子系统提供一个简化的统一接口」它不应该屏蔽子系统的所有能力只应该封装那些高频、复杂的组合调用。解决外观类只封装最常用的几组操作不要试图覆盖子系统的全部功能。需要精细控制的地方允许调用方直接访问子系统。外观模式的价值在于降低客户端与子系统的耦合不是完全隔离。6. 验收与答辩用模拟试卷和对比表做一轮自检复习到最后怎么判断自己真的掌握了而不是「看过了」这份文档给了一个很实用的收口方式练习题加模拟试卷。我的建议是把它当成验收环节来用而不是当额外的负担。具体操作分三步走。第一步合上文档拿一张白纸把七大设计原则和 23 种模式按创建型、结构型、行为型三类默写出来每个模式用一句话写清楚「它解决什么问题」。写不出来的就是没记住的回去补。第二步打开文档最后的对比表遮住结论部分自己先判断每组模式的区别再对照文档看说得对不对。比如「适配器 vs 装饰器 vs 代理」这组你能不能准确说出适配器改变接口、装饰器增强功能、代理控制访问说不清楚就回去看对应章节。第三步做模拟试卷重点看错题涉及的是哪个模式、哪个原则针对性补漏。答辩场景下有几个高频问题值得提前准备。一是「你这个项目里用了哪些设计模式为什么选它不选别的」——回答时一定要结合具体场景说清楚不用这个模式会有什么问题。二是「抽象工厂和工厂方法有什么区别」——抓住「一个产品族 vs 一个产品等级结构」这个核心差异。三是「策略模式和状态模式怎么区分」——用「客户端主动切换 vs 内部状态驱动切换」来回答。四是「单例模式有哪些实现方式各自优缺点是什么」——至少能说出饿汉式、双重检查锁、静态内部类三种。我自己的习惯是每次复习完一个模式就找一个自己写过的项目代码看看能不能用这个模式重构一小块。能重构成功说明真懂了重构完发现更复杂了说明这个场景不适合用这个模式也是一种收获。从那以后我每次准备设计模式相关的答辩或评审都强制走一遍「默写 → 对比 → 重构」这三步比反复看文档有效得多。希望这份拆解能帮你把设计模式复习从「背了忘、忘了背」的循环里拉出来真正变成一套能用在项目和答辩里的方案。完整文档里还有剩余 15 种模式的详细分析和更多实例代码需要的话可以拿去对照着过一遍。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/24 15:00:23
NetSpot Wi-Fi干扰分析实战:从信道冲突到热力图校准
2026/10/24 14:55:22
IMS计费标准3GPP TS 32.260详解:架构、消息流与常见误区
2026/10/24 14:55:22
汽车修理管理系统源码拆解:从接车到结算的完整业务闭环实现
2026/10/24 15:50:31
临床试验估计目标:定义真正想回答的科学问题
2026/10/24 15:50:31
IBM x3650 M4换主板后RAID不识别故障排查全指南
2026/10/24 15:50:31
善付通支付结算接入:DES加密、MD5签名与异步通知避坑
2026/10/24 15:50:31
Win2008 R2 RAID驱动集成:DISM注入双WIM
2026/10/24 15:50:31
WinForm医疗管理系统实战:挂号、接诊、收费、药房全流程解析
2026/10/24 15:45:31
5G AI智慧校园:业务分级、网络切片与边缘计算落地
2026/10/24 0:02:52
UDP协议实现局域网音量与关机控制:后台常驻与批量管理
2026/10/24 0:02:52
MATLAB缩进快捷键与批量格式化实战指南
2026/10/24 0:02:52
用Poco实现Qt风格信号与槽的跨平台C++方案
2026/10/24 4:01:50
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/24 4:01:49
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/24 0:59:24
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/23 10:58:39
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/23 10:58:39
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/23 10:58:39
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)