ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

设计模式速记指南:从类关系入手,轻松应对期末与大作业

2026/9/14 18:33:35 拓冰建站 浏览量
设计模式速记指南:从类关系入手,轻松应对期末与大作业 如果把设计模式当成23个需要背下来的名词那期末考试前两晚基本是崩溃的。记不住名字、记不住类图更别提现场手写一个Java或C的示例。但如果换个思路把设计模式当作“类和类之间的一种沟通协议”事情就会变得不一样。我这篇内容就围绕这个思路展开用速记的视角帮你在最短时间内抓住设计模式的骨架既不耽误应付期末、大作业也能让动手写代码时有据可依。不管你是正在准备设计模式期末复习还是为了课程大作业挠头又或者只是想搞懂工厂模式和简单工厂模式到底差在哪这篇都能给你一条清晰的路线。我翻了刘伟那本《Java设计模式》电子书也重温了《大话设计模式》里组合模式那几章加上自己在C和Java项目里实际用下来的经验把这些搅在一起换个“速记”的炒法尽量让它变成能吞下去的东西。1. 为什么“背下23个模式”是最笨的学习方式1.1 设计模式的本质是类与类之间的三种关系很多人一开始就抱着23个模式挨个背背到策略模式就忘了观察者背到组合模式就忘了适配器。这不是记忆力的问题是方法错了。设计模式并不是23个孤立的“知识点”它们本质上是在描述类与类之间如何打交道。GOF把模式分成创建型、结构型、行为型三大类这个分类不是随便分的而是在回答三个问题对象怎么来、对象怎么组合、对象之间怎么通信。想清楚这一点你就不需要背“23个模式”了只需要记住三个大抽屉然后把具体模式放进对应抽屉里。创建型的核心就是“控制对象的创建过程”它回答的是“谁负责把对象造出来怎么造造几个”结构型的核心是“把已有的类组合成更大的结构”它回答的是“多个类怎么配合才能形成一个新的、对外统一的能力”行为型的核心是“对象之间怎么分配职责、怎么协作”它回答的是“一个事情要做应该让哪个对象来做其他对象怎么感知到”。这个框架一旦建立起来后面每一个模式在你眼里都会变成一个“解决问题的方案”而不是一个“必须背下来的名词”。我当年复习时第一遍走的就是这个框架第二遍才开始逐个看类图效率比直接硬啃高很多。1.2 速记的前提先分清“模式”和“套路”的边界有件事必须在入门时就讲清楚设计模式是“套路”但不是唯一套路。很多人学完23个模式后有个毛病看什么都想套个模式写个Hello World都想用单例。这是典型的学歪了。设计模式的价值在于解决特定场景下的“变化点”如果你的代码里根本没有变化点强行上模式只会增加复杂度。速记设计模式的正确姿势是反过来先记住每个模式解决什么问题再记它长什么样。比如适配器解决的问题是“接口不兼容”装饰器解决的问题是“需要在不修改原类的前提下增强功能”代理解决的问题是“不想直接操作原始对象”策略解决的问题是“算法可能随时替换”。这些“问题”才是模式的锚点类图是后来才需要关心的东西。这也解释了为什么《大话设计模式》那本书能成为很多人的入门书因为它把所有模式都还原成了讲故事的问题场景。比如它讲组合模式是从“分公司和总公司”这种树形组织架构讲起的你一旦理解了“整体和部分需要被一致对待”组合模式的类图就自然记得住了。速记的底层逻辑就是这样先理解问题再记结构名字只是最后贴上去的标签。2. 创建型模式从工厂三兄弟到单例与原型2.1 工厂三兄弟的演进逻辑从简单工厂到工厂方法再到抽象工厂创建型模式里最常考、也最容易混淆的就是那三个“工厂”。在很多教材里简单工厂模式被放在第一个讲但它其实并不在GOF的23个模式里它只是一个最朴素的“用工厂类封装创建逻辑”的写法。简单工厂的问题在于每当你要新增一个产品类都要去改那个工厂类里的分支判断。软件设计原则里最忌讳的就是“对修改开放”这就促使了工厂方法模式的诞生。工厂方法模式的思路是把“工厂”也抽象成父类每一种产品对应一个具体的工厂子类。这样新增产品时只需要新增一个工厂子类不用修改已有代码。代价是多了一堆工厂类类数量翻倍。用食堂打饭的比喻来说简单工厂是只有一个打饭窗口你告诉阿姨要什么菜她给你打工厂方法则是每个菜都有专属窗口想吃宫保鸡丁就去2号窗口想吃鱼香肉丝就去3号窗口。再往前一步就是抽象工厂模式。这个模式解决的是“产品族”的问题它要求你的工厂能生产一组相互关联的产品而不是单个产品。比如一个现代风格家具工厂能同时生产现代沙发、现代茶几、现代椅子另一个古典风格家具工厂能生产古典沙发、古典茶几、古典椅子。抽象工厂把这一整个产品族的生产能力绑定在了一起好处是配套一致坏处是想要扩展一个产品品种非常麻烦。我把这三兄弟放在一起看简单工厂管“一个产品”工厂方法管“一种产品线的扩展”抽象工厂管“一族产品的配套”。2.2 单例模式与原型模式的共同点控制实例的“数量与来源”单例模式是考得最频繁的模式之一核心要求只有两条第一一个类只能有一个实例第二这个实例必须能被全局访问到。它的实现套路各个语言不太一样但考点几乎都集中在“懒汉式和饿汉式的区别”以及“线程安全”这两个问题上。饿汉式在类加载时就创建实例天生线程安全但启动慢懒汉式在第一次调用时才创建省资源但需要加锁。Java里还藏着双重检查锁定加volatile的做法C里简单一点的话可以直接用C11之后的局部静态变量。原型模式则是另一个有趣的思路它不通过构造函数创建新对象而是通过复制现有对象来生成新对象。这个模式对“创建成本高”或“构造函数复杂”的场景特别好用比如一份报表模板、一个大配置对象。实现时核心是深拷贝和浅拷贝的区别Java用clone()C用拷贝构造函数这里提醒一句浅拷贝只复制引用共享同一个底层对象这在很多场景会埋雷。单例和原型放在一起看一个限制数量一个复制来源都是对创建过程做特殊控制的典型。在期末卷面上创建型模式最容易出“画类图”和“写关键代码”题。我的建议是别背整段代码只背类图和核心方法签名。比如工厂方法模式只记住类图里“Product接口、ConcreteProduct、Factory抽象类、ConcreteFactory四件套”再记住工厂子类里那个create方法的返回值类型是Product就能写出来个七七八八。3. 结构型模式用“装配思维”串起适配器、装饰器、代理与组合3.1 适配器、装饰器、代理三个容易混淆的“中间层”结构型模式里最容易让人上头的是适配器、装饰器、代理这三个因为从类图上看它们都像是“在原来的类外面套了一层壳”。我第一次学的时候也觉得这三兄弟长得一模一样直到后来做项目踩了坑才真正分清楚。区分它们的方法只有一个视角看这层壳的“意图”。适配器模式解决的是“接口不兼容”问题它是把一个接口转换成客户端期望的另一个接口。打个比方你有一个Type-C接口的耳机但电脑只有USB-A口你需要一个转接头这个转接头就是适配器。它在代码里的典型场景是你有一个老类A它干的事情正是客户端需要的但它的方法签名和客户端接口对不上就用适配器包装一下。装饰器模式解决的是“在不修改原类的情况下增强功能”的问题。它的特点是“层层包裹、逐级增强”而且每一层都保持和原始对象相同的接口。理解装饰器的关键是一个场景给咖啡加牛奶加糖加完之后还是一杯咖啡。它的实现核心是继承同一个抽象类并在构造时把被装饰对象传进来这种写法让装饰器可以无限嵌套。代理模式和装饰器结构上几乎一样但意图是“控制访问而不是增强功能”。比如有时候你连不上真实对象或者不想让客户端直接接触真实对象就找个代理来转发请求代理可以在转发前后做权限检查、日志记录、延迟加载。用房产中介来类比中介不改变房子本身但它帮你过滤看房人、安排时间、签合同这种“替你做外围事”的角色就是代理。一旦从“意图”层面理解了这三个模式类图就不再是死记硬背而是顺理成章。3.2 组合模式用一棵树处理整体与部分组合模式在《大话设计模式》里被单独拎出来讲说明它在初学者眼里确实有一定门槛。其实组合模式解决的是“整体-部分”的层级结构问题核心诉求是让客户端对“单个对象”和“组合对象”的使用保持一致。最经典的例子就是文件系统文件是叶子节点文件夹是树枝节点但你无论是删除一个文件还是删除一个文件夹调用方式都是同样的delete操作。组合模式的关键类图是三个角色抽象组件Component、叶子Leaf、树枝Composite。抽象组件定义公共接口叶子和树枝都实现这个接口但叶子在add/remove这些操作上要么抛异常要么什么都不做。树枝内部要持有子组件的集合实现嵌套结构。这里有个经典考点透明式和安全式。透明式是在抽象组件里就声明add、remove方法客户端统一操作但叶子会暴露一些没意义的操作安全式是只在树枝里声明add、remove叶子没有这些方法更安全但客户端要自己判断对象类型。我实际写代码时更倾向安全式因为可以避免很多“运行时才发现叶子不能add”的尴尬。但考试时如果问哪种更“透明”就要答透明式问哪种更“安全”就答安全式这是两个方向的权衡。期末大作业里组合模式很适合用来做菜单系统、组织架构、权限树这类需求它的树形结构用数据一看就很直观也容易给老师讲解。4. 行为型模式从“谁来做”和“谁在听”切入4.1 观察者、策略、模板方法高频考点的三个关键词行为型模式一共有11个是全部分类里数量最多的但真正高频的其实就那么几个。观察者模式是考试出题率最高的行为型模式它的核心是“一对多的依赖关系”被观察者状态变化时自动通知所有观察者。你可以把它理解成微信公众号你不用天天去问作者发没发文章只要你关注了文章一更新你就收到推送。代码里的关键就是被观察者持有观察者列表状态变化后遍历列表调用update方法。Java里有现成的Observer和Observable接口C里一般用回调函数或信号槽机制实现。策略模式解决的是“算法族的自由切换”。它的核心思想是定义一组算法把每个算法封装起来让它们可以互相替换。最典型的例子是购物车里的多种优惠策略满减、打折、无门槛券每种都可以是一个策略类。策略模式最大的价值在于那些if-else把一堆分支判断改成对象间的组合关系以后加新优惠策略不影响旧代码。模板方法模式则是用好莱坞原则“不要来找我我会找你”它把算法的骨架定义在父类里把具体的步骤延迟到子类实现。比如做菜流程固定为热锅、倒油、下食材、翻炒、出锅但下什么食材由子类决定。模板方法模式的考点很简单父类里那个final的模板方法不能被重写但可变的步骤方法被抽象出来交给子类。这三个模式放在一起记忆效果很好策略模式是“整个算法替换”模板方法模式是“算法骨架固定但步骤可改”观察者模式是“状态变了要喊人”。4.2 状态模式与命令模式把动作变成对象状态模式和行为型哥们里最容易和策略模式混淆的就是状态模式因为从类图结构看它们几乎一样都是有一个环境类、一个抽象状态类和多个具体状态类。它们的本质区别在于意图策略模式下客户端主动选择算法算法之间是平级替换关系状态模式下状态是自动流转的状态对象会触发环境对象切换到另一个状态。用手机来类比飞行模式、静音模式、响铃模式之间会互相切换而且切换是状态自己触发的这就是状态模式音量大小调整策略可以随意选一种但不会自动变成另一种策略这是策略模式。命令模式是另一个值得记住的模式它把“请求”本身封装成对象这样就能把请求的发起者和执行者解耦。最简单的理解就是餐厅点餐顾客把菜单交给服务员服务员把订单传给后厨顾客不知道厨师是谁厨师也不知道顾客是谁订单这个命令对象在中间传递。命令模式的好处是支持撤销、重做、队列化操作很符合“把动作变成对象”这个抽象思路。行为型模式因为数量多速记时不要平均用力。我自己的经验是优先吃透观察者、策略、模板方法、状态这四个剩下的职责链、备忘录、中介者等模式能画出类图、说出使用场景即可。根据我对网上大量期末真题的观察出题老师也偏爱这几个剩余的模式最多出个选择题。5. 期末与大作业怎么把“速记”变成“速用”5.1 应对笔试选择题识别题目中的关键描述设计模式期末考试的题型一般就是选择题、判断题、简答题、画图题再加一个大题。选择题和判断题考的几乎都是“关键描述”和“典型场景”的对应关系这部分完全可以靠速记卡片来突击。看到“保证一个类仅有一个实例并提供全局访问点”就是单例看到“定义对象间一对多的依赖关系当一个对象状态改变时所有依赖它的对象都得到通知”就是观察者看到“提供一个创建一系列相关或相互依赖对象的接口而无需指定它们的具体类”就是抽象工厂看到“将抽象部分与实现部分分离使它们可以独立变化”就是桥接。每次做题时把题干里的关键词圈出来然后再去匹配模式。这个方法看似简单但很多人习惯先看选项再看题干结果被干扰项带偏。更稳妥的做法是先读题干在脑海里把对应的模式名说出来再看选项是不是有同名的。判断题则主要靠辨析“易混淆对”比如组合模式和继承的区别、状态模式和策略模式的区别、装饰器和代理的区别这些都是高频出题点。5.2 快速完成一份合格的大作业选模式与画类图的方法课程大作业是另一个常见难点很多人不知道选择哪些模式组合。这里给你一个我多次验证过的安全公式一个业务系统加上“工厂模式 单例模式 观察者模式”就够了最多再来一个策略模式或模板方法模式。“工厂模式”负责创建不同类型的业务对象“单例模式”负责管理全局的配置或日志组件“观察者模式”负责业务状态变化后的消息通知这样一个组合覆盖了创建型、结构型、行为型的多个维度工作量适中讲解起来逻辑也清楚。画类图有个原则不要画大而全的系统架构图要画单个模式的应用类图。老师在审大作业时最想看到的是你确实理解了某个模式的类结构而不是你画了一张谁都快看不懂的总图。比如说你选了观察者模式就单独画一个图主题接口、具体主题、观察者接口、具体观察者然后把它们的关系用箭头标清楚再配上一段十几行的核心代码即可。代码的关键是体现“触发通知”的核心机制而不是整个业务系统的所有代码。用C还是Java写大作业主要看课程要求。Java在表现面向对象特性上更直观C则需要特别注意虚析构函数和智能指针的使用。我用C写过设计模式大作业如果父类析构函数不是虚函数那么多态删除子类对象时就会内存泄漏这种问题老师一眼就能看出来而且直接影响代码分数。还有一个很实用的小技巧思考“这个设计模式解决了什么问题、如果不用会怎样”。不管是面试还是答辩这个问法几乎一定会出现。能回答出“因为我的系统里有多个产品类需要被动态创建如果不用工厂我就得在客户端写一堆if-else”这种水平就已经超过很多人了。平时练习时试试用30秒把这个模式讲明白不停顿、不卡壳练得多了自然就形成记忆了。6. 我在实际复习中用的一套速记卡片与易错点清单6.1 把“描述-场景-类图”三级关键字写进卡片我复习设计模式时用的方法是做速记卡片正面写场景描述或模式意图反面写模式名称和类图关键词。比如正面写“一个类只能有一个实例且提供一个全局访问点”反面写“单例模式Singletonprivate构造器static getInstance”正面写“将请求封装成对象从而实现请求者和执行者的解耦”反面写“命令模式CommandInvokerReceiverexecute()”。这样的卡片一套也就三四十张看起来好像很多但每天过两遍三天基本就能形成条件反射。和普通笔记相比这种卡片的优势在于它是“看描述想答案”的模拟的是考试时的提取过程而不是“看笔记复读”的再认过程。提取过程记忆效果远好于再认这也是认知心理学里一个很基础的原则。我当时还把创建型、结构型、行为型分别用不同颜色的卡片区分扫描复习时只要拿着一叠卡片上下翻就能顺便回忆起模式所属的分类。6.2 三个常见误区乱套模式、忽略别名、混淆变体误区一为了用模式而用。大作业里最常见的问题是有人为了凑齐几十个模式把一个很简单的需求套了五六层装饰器代码看似炫技实际可维护性极差。老师评分的重点一定是对模式“恰当使用”而不是“使用数量多”。一个系统里能用好两三个模式比硬塞七八个模式得分更高。误区二不记模式的别名和英文名。面试或者阅读源码时经常碰到英文术语比如观察者模式也叫发布-订阅模式工厂方法也叫虚拟构造适配器也叫Wrapper。这些别名不一定出现在教材里但在实际项目交流中经常碰到。建议速记阶段就把英文别名写进卡片里一次记牢。误区三只记类图不记代码。类图是地图代码是路。只看地图永远不知道这段路到底怎么走。这在小公司面试和部分课程答辩中影响不大但一旦碰上现场手写代码或者上机考试只背类图的人就很容易卡壳。最好的练习方式是每个模式不看教科书自己从类图推导写出一个最小实现写的多了自然就变成肌肉记忆。6.3 针对C和Java的额外提醒如果你主要看刘伟那本Java实现的书注意Java的接口、抽象类和C的纯虚函数在表达“接口”语义时虽然相似但细节不同。C没有真正的interface关键字通常用抽象基类替代Java里接口可以有默认方法C里可以用带默认实现的虚函数。C还有析构顺序、深拷贝、移动语义等一堆坑。而Java则要留意内存泄漏问题观察者模式中主题对象持有观察者的强引用如果观察者销毁了但没有从主题的观察者列表中移除内存就会一直被占着。很多人学观察者模式时只看“通知”的代码忽略了“删除观察者”这个操作这在常驻服务里是会出事故的。另外如果你打算用C写大作业单例模式可以用Meyers Singleton也就是函数内局部静态变量的写法简洁且线程安全。相比手写双重检查锁代码量少、不容易错关键还能在答辩时讲清楚“C11之后局部静态变量初始化是线程安全的”这个知识点是个性价比很高的加分点。Java那边则推荐用枚举写单例这个做法Joshua Bloch在Effective Java里专门写过虽然看起来不像传统单例但反序列化和反射攻击都无法破坏它是个很硬核的知识点。看完这些应该能感受到设计模式不是一个需要死记硬背的科目而是一门需要“场景、结构、意图”三者来回对照思考的学问。我的建议是第一遍按分类顺序通读第二遍按“描述卡片”做自测第三遍用每个模式写一个至少能编译运行的最小示例这样三轮下来无论期末还是大作业都基本稳了。至于那些边边角角的变体和少用模式就算记不全也比合上书本一头雾水要强得多。