设计模式复习总图:七大原则与二十三种模式完整知识骨架 简介这份《大话设计模式复习》文档面向具备一定面向对象编程基础、工作1至3年的研发人员系统梳理设计模式的核心知识体系。内容从设计模式的定义、分类、特点与应用场景切入详细讲解单一职责、开放-封闭、依赖倒转、里氏代换、迪米特法则、合成/聚合及接口隔离七大设计原则并深入剖析抽象工厂、策略、外观、适配器、组合、单例、中介者七种常用模式以及其余十五种模式的UML类图、基础代码与实例。文档还横向对比不同模式的差异总结模式选择的关键维度并附练习题与模拟试卷辅助巩固。资源包为单个docx文件约3.66MB结构完整、目录清晰便于按章节检索学习。目前已有191人学习适合希望提升代码可维护性、可扩展性与复用性并在实际项目中灵活选用设计模式的开发者参考。1. 设计模式复习总图从七大原则到二十三种模式的完整知识骨架设计模式这块内容最怕的不是记不住而是脑子里没有一张总图。很多人复习时翻开资料就从单例模式开始背背到代理模式已经忘了抽象工厂在讲什么最后脑子里只剩一堆零散的类图。真正有效的复习路径是先建立分类坐标系创建型管对象怎么生结构型管类与对象怎么拼行为型管对象之间怎么通信与分责。三大类共二十三种经典模式加上七大设计原则作为底层判据再配合易混淆模式对比表才构成一个可检索、可推导的复习体系。这份笔记梳理的就是这样一条从原则到模式、从单模式拆解到跨模式对比的完整链路适合已经写过面向对象代码、正在系统复习或准备面试的人拿来当查漏补缺的地图用。2. 七大设计原则模式背后的判据与易混边界2.1 七条原则各自管什么设计原则不是拿来背的是拿来判断“这个模式为什么长这样”的。梳理下来会发现二十三种模式几乎都能回溯到某几条原则的约束。原则一句话核心典型落地模式单一职责 SRP一个类只有一个引起变化的原因计算器运算类拆分开放-封闭 OCP对扩展开放对修改关闭策略模式新增算法依赖倒转 DIP高低层都依赖抽象细节依赖抽象工厂模式依赖产品接口里氏代换 LSP子类必须能替换父类且行为契约不变正方形与矩形的经典反例迪米特法则 LOD不和陌生人说话通过第三者转发中介者模式合成/聚合 CARP优先组合而非继承装饰模式接口隔离 ISP用多个专门接口代替一个总接口动物接口拆分为飞行、陆地这张表建议反复看因为后面每一种模式的分析都会回到这里。比如抽象工厂模式它同时踩中依赖倒转和合成/聚合但在新增产品等级结构时会违反开放-封闭——这就是原则之间的张力也是考试和面试最爱问的地方。2.2 最容易搞混的三组原则依赖倒转 vs 里氏代换。依赖倒转讲的是“依赖谁”——依赖抽象不依赖具体里氏代换讲的是“替换后还行不行”——子类替换父类后行为不能变。一个管方向一个管契约。迪米特法则 vs 接口隔离。迪米特管的是“少跟不相关的类直接通信”接口隔离管的是“别让类依赖它用不到的方法”。前者是通信路径问题后者是接口粒度问题。合成/聚合 vs 开放-封闭。合成/聚合是实现开放-封闭的手段之一——通过组合而非继承来扩展功能装饰模式就是典型。但开放-封闭还可以通过策略、工厂等模式实现所以两者不是一回事。提示复习原则时不要孤立背定义每一条都找一个具体模式作为锚点回忆时先想模式再反推原则比正着背快得多。3. 七大重点模式拆解抽象工厂、策略、外观、适配器、组合、单例、中介者3.1 抽象工厂模式产品族的创建接口抽象工厂的核心是“产品族”概念。所谓产品族是指位于不同产品等级结构、功能相关联的产品组成的家族。比如数据库访问组件中User 表和 Department 表就是两个产品等级结构而 SqlServer 系列和 Access 系列就是两个产品族。角色分工抽象工厂 AbstractFactory声明创建产品族的方法如 createProductA()、createProductB()具体工厂 ConcreteFactory实现工厂方法创建具体产品族抽象产品 AbstractProduct定义产品接口具体产品 ConcreteProduct实现抽象产品接口内部包含业务逻辑// 抽象工厂接口声明创建两个产品等级结构的方法 public interface AbstractFactory { AbstractProductA createProductA(); AbstractProductB createProductB(); } // 具体工厂1创建产品族1 public class ConcreteFactory1 implements AbstractFactory { public AbstractProductA createProductA() { return new ProductA1(); } public AbstractProductB createProductB() { return new ProductB1(); } } // 客户端只依赖抽象工厂和抽象产品 AbstractFactory factory1 new ConcreteFactory1(); AbstractProductA a1 factory1.createProductA(); AbstractProductB b1 factory1.createProductB();参数说明createProductA() 和 createProductB() 分别对应两个产品等级结构具体工厂决定返回哪个产品族的实例。客户端只持有 AbstractFactory 类型引用切换产品族时只需换一个具体工厂。适用场景对象属于同一产品族需一起使用系统不依赖具体产品类系统只消费某一个产品族。优点是分离接口与实现符合依赖倒转缺点是新增产品等级结构需修改抽象工厂和所有具体工厂违反开放-封闭。AbstractFactory 与 Factory 的区别AbstractFactory 为创建一组相关或依赖的对象提供接口Factory 为一类对象提供创建接口。一个管“族”一个管“个”。3.2 策略模式算法的可互换封装策略模式的定义是定义一系列算法将每个算法封装到具有公共接口的独立类中使其可互换。类的划分基础是抽象具有相同属性和功能的对象的抽象集才是类。interface Strategy { void doAlgorithm(); } 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 切换算法。商场收银系统中正常收费、满减、打折就是三个具体策略收银台是 Context。策略模式的关键在于客户端必须知道有哪些策略可选并主动选择。这和状态模式不同——状态模式的状态切换通常由上下文或状态自身驱动客户端不感知。3.3 外观模式与适配器模式一个简化一个转换外观模式为子系统提供统一的高层接口让子系统更容易使用。它不改变子系统本身只是加了一层门面。适配器模式则是将一个类的接口转换成客户端期望的另一个接口解决的是接口不兼容问题。两者的核心区别外观是“简化调用”适配器是“转换接口”。外观模式下客户端直接调用外观类不关心子系统内部适配器模式下客户端调用目标接口适配器内部委托被适配者。3.4 组合模式与单例模式树形结构与全局唯一组合模式将对象组合成树形结构以表示“部分-整体”的层次关系使得客户端对单个对象和组合对象的使用具有一致性。典型场景是文件系统、UI 控件树。单例模式保证一个类只有一个实例并提供全局访问点。复习时重点注意多线程环境下的实现方式差异饿汉式在类加载时就创建实例线程安全但不支持延迟加载懒汉式需要双重检查锁定或静态内部类来兼顾延迟加载和线程安全。3.5 中介者模式把网状依赖变成星形依赖中介者模式用一个中介对象封装一系列对象之间的交互使各对象不需要显式地相互引用。迪米特法则在这里体现得最明显——同事类之间不直接通信全部通过中介者转发。典型场景是 GUI 对话框中多个控件之间的联动一个下拉框的选择影响按钮是否可用、文本框是否可编辑。如果没有中介者每个控件都要持有其他控件的引用依赖关系变成网状引入中介者后变成星形每个控件只认识中介者。4. 剩余十五种模式速览从简单工厂到访问者4.1 创建型补充简单工厂、工厂方法、原型、建造者简单工厂模式严格来说不算 GoF 二十三种之一但它是理解工厂方法的基础。简单工厂用一个工厂类根据参数决定创建哪种产品工厂方法将创建延迟到子类每个具体工厂对应一种产品抽象工厂则对应产品族。建造者模式与工厂模式的区别工厂模式关注“创建什么产品”建造者模式关注“如何一步步组装一个复杂对象”。建造者通常有 buildPartA()、buildPartB()、getResult() 这样的步骤接口适合构建过程稳定但表示可变的场景。原型模式通过克隆现有对象来创建新对象适用于创建成本高或需要保存对象状态的场景。与单例模式的区别单例保证全局唯一原型保证可以复制出多个相同实例。4.2 结构型补充装饰、代理、桥接、享元装饰模式通过组合而非继承来动态扩展对象功能符合合成/聚合原则。代理模式为其他对象提供一种代理以控制对这个对象的访问典型场景是远程代理、虚拟代理、保护代理。装饰器与代理的区别装饰器关注“增强功能”代理关注“控制访问”。装饰器通常由客户端主动组合代理通常对客户端透明。桥接模式将抽象部分与实现部分分离使它们可以独立变化。享元模式通过共享技术有效支持大量细粒度对象关键是区分内部状态可共享和外部状态不可共享。4.3 行为型补充模板方法、观察者、状态、命令、责任链、备忘录、访问者、迭代器、解释器模板方法模式在父类定义算法骨架将某些步骤延迟到子类实现。观察者模式定义一对多依赖当一个对象状态改变时所有依赖者收到通知。状态模式允许对象在内部状态改变时改变行为看起来像换了类。命令模式将请求封装为对象支持撤销和队列。责任链模式将请求沿处理者链传递直到被处理。备忘录模式在不破坏封装的前提下捕获并恢复对象内部状态。访问者模式在不改变元素类的前提下定义新操作。迭代器模式提供顺序访问聚合元素的方法。解释器模式给定语言定义文法表示及解释器。注意行为型模式最容易混的是策略 vs 状态、观察者 vs 中介者、责任链 vs 中介者下一章的对比表专门处理这些。5. 易错与易漏点模式对比中最容易翻车的五组关系5.1 策略 vs 状态谁决定切换易漏点把策略模式和状态模式当成一回事。为什么漏两者都有 Context 和抽象接口UML 结构几乎一样。怎么补记住切换的主动权不同——策略模式由客户端选择并设置策略状态模式由上下文或状态自身驱动切换客户端通常不感知状态变化。5.2 适配器 vs 装饰器 vs 代理结构相似但意图不同易漏点三者都是“包一层”分不清什么时候用哪个。为什么漏UML 类图结构高度相似都是持有被包装对象的引用。怎么补适配器改变接口装饰器增强功能代理控制访问。适配器通常包装不兼容的接口装饰器包装同接口对象并添加行为代理包装同接口对象并控制调用时机。5.3 观察者 vs 中介者一个广播一个转发易漏点把观察者和中介者都当成“解耦”手段混用。为什么漏两者都涉及多个对象之间的通信解耦。怎么补观察者是目标直接通知所有观察者一对多广播中介者是同事类之间不直接通信全部通过中介者转发多对多变成星形。5.4 简单工厂 vs 工厂方法 vs 抽象工厂维度不同易漏点把三个工厂当成同一维度的递进关系。为什么漏名字都带“工厂”容易按复杂度排序记忆。怎么补简单工厂是“一个工厂根据参数创建多种产品”工厂方法是“每个产品对应一个工厂”抽象工厂是“每个工厂创建一族产品”。简单工厂是工厂方法的简化特例抽象工厂是工厂方法的多产品等级扩展。5.5 单例 vs 原型唯一 vs 复制易漏点认为单例和原型都是“控制对象数量”的模式。为什么漏两者都涉及对象创建的控制。怎么补单例保证全局只有一个实例原型保证可以复制出多个相同实例。单例限制数量原型提供复制机制。6. 复习清单与查漏补缺从模式选择维度到模拟自测复习到最后一轮最有效的方式不是从头翻资料而是拿一张模式选择维度表做自测。下面这张表梳理了选模式时最关键的几个判断维度。判断维度问题对应模式对象创建创建逻辑复杂还是产品族工厂方法/抽象工厂/建造者接口不兼容需要转换接口吗适配器功能扩展需要动态添加功能吗装饰器访问控制需要控制对象访问吗代理算法切换需要运行时切换算法吗策略状态驱动行为随状态改变吗状态通信解耦多对象通信太复杂中介者/观察者请求处理需要沿链传递请求吗责任链撤销恢复需要保存和恢复状态吗备忘录树形结构部分-整体层次组合自测方法拿一张白纸先默写七大原则再按创建型、结构型、行为型三类默写所有模式名称然后对每个模式写出“一句话定义 一个适用场景 一个易混模式”。写不出来的就是漏洞回去翻对应章节。// 自测代码模板用最小代码验证是否真正理解某个模式 // 以策略模式为例如果能不查资料写出以下结构说明基本掌握 interface Strategy { void execute(); } class ConcreteStrategyA implements Strategy { public void execute() { System.out.println(策略A); } } class Context { private Strategy strategy; public Context(Strategy s) { this.strategy s; } public void run() { strategy.execute(); } } // 测试切换策略验证客户端无需修改参数说明Context 构造函数注入 Strategyrun() 委托执行。如果能独立写出并解释为什么这样设计符合依赖倒转和开放-封闭说明策略模式过关。最后一轮复习建议按这个顺序走先过一遍七大原则再按三类默写模式名称然后重点看易混淆对比表最后用模拟题自测。我自己的习惯是每次复习设计模式都强制走一遍“原则→分类→模式→对比→自测”这条链路因为跳过任何一步都会在面试或实际选型时卡壳。最容易忽略的其实是原则和模式之间的映射关系——很多人能背出二十三种模式的名字但被问到“这个模式体现了哪条原则”时就答不上来而这恰恰是区分死记硬背和真正理解的分水岭。希望这份梳理能帮到你。本文还有配套的精品资源点击获取