☰
软考软件设计师:23种设计模式分类、六大原则与下午题填空
2026/10/1 23:29:54 网站建设 项目流程

1. 为什么设计模式是软考中级里性价比最高的一块分

设计模式这一章,我前后啃了三遍。第一遍是在教材上划重点,第二遍是对着真题找规律,第三遍是真正把十几个高频模式的代码手敲了一遍。三遍下来最大的感受是:这一章不是"背得多就赢",而是"看得懂类图、认得出骨架、写得出那一行空"。很多人复习到第七章的时候整个人是懵的——23种模式名字都念不顺,更别说区分了。可实际上,这一章的投入产出比在整个软件设计师知识体系里排得进前三:内容边界清晰、考法固定、重复率高,属于典型的"花三天能换来稳定分数"的模块。

1.1 一个下午题考生的真实困境

我身边有个朋友,上午题能考55分以上,结果卡在下午题上。他跟我说,下午题最后那道面向对象大题,代码长得像天书,类图里一堆框和箭头,读完题干五分钟就过去了,最后只能空着几个空交卷。这个场景特别典型——很多人不是不懂面向对象,而是没建立"模式识别"的条件反射。看到Context里持有一个接口类型的成员变量、还有一个setXxx()方法,脑子里应该立刻弹出"这是策略模式或者状态模式";看到abstract class实现了接口又持有同类型接口的成员变量,那基本就是装饰器。这种反射不是天生的,是靠反复看同类骨架练出来的,而这恰恰是这一章最容易练成的东西。

所以这篇笔记的定位很明确:它不是教材的替代品,而是把教材第七章那几十页压缩成一套可操作的识别系统和填空套路。教材告诉你"工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪个类",但它不会告诉你答题卡上的那个空为什么一定落在factory.createProduct()这一行。我下面要写的,主要是后面这部分。

1.2 23种模式在考试里到底值多少分

先把这个账算清楚,因为这直接决定你该花多少时间。软件设计师的下午卷一共五道大题,每题15分,最后一道是面向对象程序设计,通常是 Java 和 C++ 二选一,题干给出一段业务描述、一张类图,然后留出四到五个空让你填代码或者填类名。这道题里出现设计模式的概率非常高,我做过的那几年真题里,策略、观察者、工厂方法、装饰器、适配器、组合、模板方法这几个轮着出现。

题型设计模式相关占比我的建议投入
上午选择题一般2到4分靠识别套路得分,别死磕冷门模式
下午面向对象大题15分整题,模式是核心线索高频10个模式必须能手写骨架
下午UML题类图关系涉及组合、聚合、依赖顺带复习,不单独投入
上午算法与数据结构几乎不涉及忽略

这张表的意思是:把精力集中在十来个高频模式上,剩下十来个只需要能认名字、知道大概意图就够了。解释器模式、访问者模式、备忘录模式这些,上午题偶尔冒一个,考的是"这个模式属于哪一类"或者"它的意图是什么",你只要知道访问者是"在不改变元素类的前提下定义作用于这些元素的新操作"就足够了,犯不着去把双分派写一遍。反过来,策略模式和观察者模式我是强烈建议手写到肌肉记忆的,因为它们在下午题里出现的频率实在太高了。

1.3 这门笔记适合谁看、不适合谁看

适合的人群:正在备考软件设计师中级、已经学过 Java 或者 C++ 基础语法、能看懂简单的 UML 类图,但一看到大段代码就发怵的人。如果你是零基础连接口和抽象类都分不清,那得先把面向对象那两章补上,设计模式是建在这块地基上的。

不适合的人群:已经能熟练写出十几个模式、只是想找点新东西的人。这篇东西的深度是考试导向的,不是工程架构导向的。说到工程实践,我得提醒一句,考试里的模式写法和真实项目里的写法差别挺大。真实项目里没人会为了一个只有两种排序方式的需求去写一套完整的策略体系,往往一个if-else就完事了,过度设计反而是坑。考试是反过来,它默认你的设计必须是"可扩展"的,所以你得按标准骨架来。这个心理预期如果不调整,做题时很容易觉得"这么写太啰嗦了吧",然后选错。

2. 把23种模式塞进脑子的分类骨架

23个名字硬背绝对会串。我试过按字母顺序背,结果第二天就全混了。后来换成按"它们各自解决什么问题"来归类,记忆负担一下子小了很多。Gang of Four 那本书本身就把23种分成了三个大类:创建型管"对象怎么造出来",结构型管"类和对象怎么拼装",行为型管"对象之间怎么协作分工"。这个分类不只是记名字用的,考试里问"以下哪个属于结构型模式",你要是分类记混了就是白丢分。

2.1 创建型5种:围绕"对象怎么生出来"

创建型一共五个:工厂方法、抽象工厂、建造者、原型、单例。这五个模式的共同点是它们都在解决"直接 new 一个对象有什么不好"这个问题。直接 new 的问题在于耦合——调用方知道了具体的类名,将来换实现就得改代码。

  • 工厂方法:定义一个创建对象的接口,让子类决定实例化哪一个类。它把"造什么"这件事推迟到子类。关键词是"一个产品等级结构"。
  • 抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,不需要指定具体类。关键词是"产品族"。比如一整套 UI 控件(按钮、文本框、滚动条)在 Windows 风格和 Mac 风格之间切换,这就是抽象工厂。
  • 建造者:把一个复杂对象的构建与它的表示分离,同样的构建过程可以创建不同的表示。关键词是"分步骤、有顺序"。
  • 原型:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。关键词是"克隆、clone"。
  • 单例:保证一个类仅有一个实例,并提供一个访问它的全局访问点。关键词是"私有构造、静态实例、静态获取方法"。

我记这一组用的类比是开餐馆。单例是整个店只有一口锅;工厂方法是这家店有个"做菜师傅"的岗位,具体谁来炒由分店决定;抽象工厂是"川菜套餐"和"粤菜套餐"整套换;建造者是按固定流程组装一份套餐,先主食再汤再饮料;原型是照着现成的一份菜复制一份出来。

2.2 结构型7种:围绕"类与对象怎么拼起来"

结构型有七个:适配器、桥接、组合、装饰器、外观、享元、代理。这一组的共同主题是"组合优于继承",它们都在用某种方式把已有的东西拼成更大的结构,同时避免继承层次爆炸。

  • 适配器:把一个类的接口转换成客户希望的另一个接口。关键词是"接口不兼容、转换器"。
  • 桥接:把抽象部分与它的实现部分分离,使它们都可以独立变化。关键词是"两个维度的变化"。
  • 组合:把对象组合成树形结构以表示"部分-整体"的层次结构。关键词是"树、递归、叶子节点和容器节点"。
  • 装饰器:动态地给一个对象添加一些额外的职责。关键词是"包裹、层层叠加、和原对象实现同一个接口"。
  • 外观:为子系统中的一组接口提供一个一致的界面。关键词是"简化调用、总开关"。
  • 享元:运用共享技术有效地支持大量细粒度的对象。关键词是"缓存、池、内部状态和外部状态"。
  • 代理:为其他对象提供一种代理以控制对这个对象的访问。关键词是"中间人、访问控制、延迟加载"。

这一组的类比我用的是装修。适配器是插座转换头;桥接是把"款式"和"颜色"两个维度拆开;组合是文件夹里还能放文件夹;装饰器是给一个蛋糕一层层抹奶油加水果;外观是装修队的项目经理,你只跟他对接;享元是共用模具;代理是中介。

2.3 行为型11种:围绕"对象之间怎么分工协作"

行为型最多,十一个:职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者。这一组的核心是"把易变的行为抽出来,让对象之间通过协作完成一件事",而不是把逻辑全堆在一个类里。

高频的其实就四五个:策略、观察者、模板方法、职责链、状态。剩下的了解意图即可。

  • 职责链:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。关键词是"一串处理器、逐个传递、审批流"。
  • 命令:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化。关键词是"撤销、排队、把操作变成对象"。
  • 迭代器:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。关键词是"遍历、hasNext/next"。
  • 中介者:用一个中介对象来封装一系列的对象交互。关键词是"星形结构替代网状结构"。
  • 备忘录:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。关键词是"存档、回滚、Memento"。
  • 观察者:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。关键词是"订阅、监听、通知"。
  • 状态:允许一个对象在其内部状态改变时改变它的行为。关键词是"状态驱动的行为切换"。
  • 策略:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。关键词是"算法族、可替换"。
  • 模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。关键词是"父类定骨架、子类填步骤"。
  • 访问者:表示一个作用于某对象结构中的各元素的操作。关键词是"双分派、不改变元素类"。
  • 解释器:给定一个语言,定义它的文法的一种表示,并定义一个解释器。关键词是"表达式、语法树、递归下降"。

2.4 一张表把23种模式的核心意图钉死

下面这张表我建议直接抄在笔记本第一页,复习时不看教材先自己填一遍,填不出来的再回去翻。

分类模式一句话意图关键词锚点
创建型工厂方法子类决定实例化哪个类一个产品等级
创建型抽象工厂创建一系列相关对象产品族
创建型建造者分步构建复杂对象构建过程与表示分离
创建型原型拷贝创建新对象clone
创建型单例全局唯一实例私有构造
结构型适配器接口转换兼容
结构型桥接抽象与实现分离两个维度
结构型组合树形部分整体递归
结构型装饰器动态添加职责同接口包裹
结构型外观简化子系统调用统一入口
结构型享元共享细粒度对象缓存池
结构型代理控制对象访问中间人
行为型职责链请求沿链传递审批
行为型命令请求封装成对象撤销
行为型解释器定义语言文法表达式树
行为型迭代器顺序访问聚合遍历
行为型中介者封装对象交互星形
行为型备忘录保存与恢复状态存档
行为型观察者一对多通知订阅
行为型状态状态改变行为状态机
行为型策略算法可替换算法族
行为型模板方法父类定骨架钩子方法
行为型访问者不改变元素加操作双分派

3. 六大设计原则:所有模式背后的底层宪法

设计模式不是凭空发明的,它们背后有一套共同的原则。搞懂这套原则,很多模式你甚至能自己"推导"出来,而不是死记。而且上午题里会直接考原则本身,尤其"里氏替换"和"依赖倒置"这两条,我至少见过三次,每次都有人做错。

3.1 单一职责与开闭:最常被引用的两条

单一职责原则说的是就一个类而言,应该仅有一个引起它变化的原因。它的判断标准特别好用:当你描述一个类的职责时,如果句子里出现了"和"字,比如"这个类负责解析配置和发送邮件",那大概率就是违反单一职责了。

开闭原则说的是软件实体应该可以扩展,但是不可修改。这句话初看有点矛盾——不能改,又要扩展,怎么办?答案是抽象。加新功能的时候不改老代码,而是新增一个子类或者新增一个实现类。设计模式里几乎所有模式都是开闭原则的具体实现手段。工厂方法是加新实现类而不是改 if-else;策略模式是加新策略类而不是改那段 switch;装饰器是加新装饰类而不是改原类。

这里有个考试上的坑我得说一下:题干里如果描述"新增一种类型时,只需要增加一个新的类,不需要修改原有代码",那对应的就是开闭原则,而不是单一职责。这两个经常一起出现,别串。

3.2 里氏替换与依赖倒置:最容易答错的两条

里氏替换原则的原始定义有点绕:所有引用基类的地方必须能透明地使用其子类的对象。翻译成人话就是——子类必须能够替换掉父类,而且程序行为不发生奇怪的变化。反例是经典的"正方形继承长方形":长方形的宽和高可以独立变化,正方形的宽高必须相等,你把正方形当成长方形用,设置宽为5高为3,结果面积算出来是9不是15,行为就崩了。

考试里这条常以"子类可以替换父类"的表述出现,也可能出现在代码题里让你判断某个继承关系是否合理。

依赖倒置原则说的是高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。人话版:面向接口编程,别面向实现编程。这条原则是策略模式、工厂方法、观察者模式等等一大票模式的理论基础。你看到某个类里成员变量的类型是接口而不是具体类,那就是依赖倒置的体现。

我用生活化的方式记这两条:里氏替换回答的是"儿子能不能替父亲上班"(能不能替换),依赖倒置回答的是"老板应该找岗位还是找人"(应该依赖抽象)。

3.3 接口隔离与迪米特:被低估的两条

接口隔离原则:使用多个专门的接口比使用单一的总接口好,不应该强迫客户依赖它们不用的方法。反例是一个超大的接口里有二十个方法,某个实现类只需要其中两个,剩下十八个都得写空实现——这就是接口污染。

迪米特法则,又叫最少知识原则:一个对象应该对其他对象有尽可能少的了解。翻译成做题语言:类 A 里不要出现b.getC().getD().doSomething()这种链式调用,因为 A 需要了解 C 和 D 的结构。中介者模式和外观模式都是迪米特法则的落地。

这两条在上午题里出现的频率比前四条低,但一旦出现,往往以"以下说法错误的是"这种形式来考,干扰项通常是把两条原则的描述对调。我的应对方式是记住关键词:接口隔离的关键词是"专门接口、不强迫依赖",迪米特的关键词是"少了解、少通信"。

3.4 原则与模式的对应关系表

复习到后期,我习惯拿这张表做交叉验证。看到一个模式,问自己它主要在维护哪条原则。

设计原则主要体现它的模式
单一职责外观、代理、中介者
开闭工厂方法、抽象工厂、策略、装饰器
里氏替换模板方法、组合
依赖倒置策略、观察者、工厂方法、桥接
接口隔离适配器、外观
迪米特中介者、外观、代理

提示:这张表不是标准答案,而是一张"联想触发器"。考试不会直接问"策略模式体现了哪条原则",但它会在题干描述里埋线索,你脑子里有这张关联表,读题干的速度会快很多。

4. 下午题代码填空:高频模式的填空套路

下午题最后的面向对象大题,很多人做不完是因为顺序搞反了——先从头读代码,读到一半就迷路了。我的做法是先扫类图,再定位模式,最后才看代码。类图里藏着80%的答案信息,尤其是继承关系和成员变量类型。下面我按几种高频模式,说说那些空通常落在哪里。

4.1 先看类图还是先看代码——我的做题顺序

我的顺序是这样三步:

  1. 扫类图里的接口和抽象类。找那个被多个类实现的接口,它定义了这套设计的"契约"。这个接口名往往就是解题钥匙,比如叫SortStrategy、Observer、Component。
  2. 看谁持有谁的引用。如果一个Context类里有一个接口类型的成员变量,并且有setXxx()方法,那基本可以锁定策略模式或状态模式。
  3. 回到代码填空处,判断这个空要的是"类名、方法名、还是调用语句"。这一步特别关键。有些空填的是类型,有些空填的是new Xxx(),有些空填的是strategy.method(args)。填错了类型,一分不给。

我实测下来,这三步能覆盖八成以上的空位判断,剩下两成靠题干里的业务描述补。

4.2 策略模式填空:为什么空永远落在接口调用那一行

策略模式的骨架长这样:

interface DiscountStrategy { double calculate(double price); } class NormalDiscount implements DiscountStrategy { public double calculate(double price) { return price; } } class VipDiscount implements DiscountStrategy { public double calculate(double price) { return price * 0.8; } } class PriceContext { private DiscountStrategy strategy; public PriceContext(DiscountStrategy strategy) { this.strategy = strategy; } public void setStrategy(DiscountStrategy strategy) { this.strategy = strategy; } public double finalPrice(double price) { return strategy.calculate(price); } }

你看这个结构,考试里最常挖的空就是strategy.calculate(price)这一行。为什么会挖这里?因为这一行是"上下文委托给策略"的关节,是整套设计里最核心的一句。它前面那个成员变量声明private DiscountStrategy strategy;也经常被挖。

我的经验是:策略模式的空,十个里有七个落在"上下文调用策略方法"和"成员变量声明"这两个位置。另外,如果题干给出了new VipDiscount()这样的调用,别惊讶,那说明具体策略的选择被放在了客户端,这也是策略模式的正常用法。

4.3 工厂方法与抽象工厂的空位规律

工厂方法里最典型的空是返回语句。因为工厂方法的实现类负责返回具体产品:

abstract class LoggerFactory { public abstract Logger createLogger(); } class FileLoggerFactory extends LoggerFactory { public Logger createLogger() { return new FileLogger(); } }

那个return new FileLogger();就是高频空位。抽象工厂的填空稍微复杂一点,因为它涉及产品族,往往要你填某个具体工厂里创建两个产品的代码:

interface SkinFactory { Button createButton(); TextField createTextField(); } class SpringSkinFactory implements SkinFactory { public Button createButton() { return new SpringButton(); } public TextField createTextField() { return new SpringTextField(); } }

这一组的判断诀窍是:看类图里工厂接口的方法返回值是不是多个不同的产品接口。是多个,那就是抽象工厂;只有一个,那就是工厂方法。这个判断我考试时用过不止一次,命中率很高。

4.4 观察者模式:attach 与 notify 的固定骨架

观察者模式在下午题里的骨架极其固定,几乎可以默写:

interface Observer { void update(String message); } class Subject { private List<Observer> observers = new ArrayList<>(); public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } }

这段代码里可以挖的空有四个:observers.add(observer)、observers.remove(observer)、循环语句、observer.update(message)。观察者的题干通常会给出很明显的业务描述,比如"当库存发生变化时,采购部门和销售部门都要收到通知",看到这种一对多的描述,直接锁定观察者。

注意:有些版本会把这个类叫Subject,有些叫ConcreteSubject,还有的会把注册方法叫registerObserver。名字不一样没关系,你要认的是"一个 List 存观察者 + 一个循环遍历通知"这个结构。

4.5 装饰器与代理:继承同一个接口是关键线索

装饰器和代理在类图上的共同特征是:装饰类/代理类既实现了目标接口,又持有一个目标接口类型的成员变量。这个"双重身份"是它们最醒目的标志。

interface Coffee { double cost(); } class Espresso implements Coffee { public double cost() { return 10; } } abstract class CoffeeDecorator implements Coffee { protected Coffee coffee; public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; } public double cost() { return coffee.cost(); } } class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } public double cost() { return super.cost() + 3; } }

这里面最常见的空是return coffee.cost();和return super.cost() + 3;。前者是委托给被装饰对象,后者是在原有行为上追加。

代理模式的骨架和这个几乎一样,区别在于意图:装饰器是"增强功能",代理是"控制访问"。考试如果题干说"在访问真实对象之前先进行权限校验",那就是代理;如果题干说"可以动态地给对象增加额外的功能,比如加奶、加糖",那就是装饰器。判断依据在业务描述里,不在代码结构里,这一点特别容易栽跟头。

5. 最容易混淆的六组模式对比

23个模式里,真正让人头疼的不是记不住,而是分不清。下面这六组是我自己反复搞混过的,也是考试里干扰项最爱出现的地方。

5.1 策略 vs 状态

这两个在代码层面几乎是双胞胎:都是上下文持有一个接口,都把具体行为委托出去。区别在于行为切换的驱动者是谁。

策略模式下,客户端主动选择用哪个策略,策略之间是平等可替换的,互相不知道对方存在。状态模式下,状态之间的切换往往由状态自身触发,而且状态之间是有"迁移关系"的,A 状态处理完可能自动转到 B 状态。

一个判断技巧:题干里出现"由客户端决定""可自由替换"这类描述,是策略;出现"状态流转""当前状态决定下一步""自动切换"这类描述,是状态。

5.2 工厂方法 vs 抽象工厂

这组其实不难,但考场上紧张的时候容易看走眼。核心区别只有一条:产品的数量。

工厂方法只有一个产品接口,一个工厂对应一个产品。抽象工厂有一个产品族,一个工厂负责创建多个相关联的产品。类图上看得最清楚——抽象工厂的工厂接口里会有两到三个返回不同类型产品的方法。

还有一个细节:抽象工厂里的每个创建方法,本质上就是一个工厂方法。所以你可以理解成抽象工厂是工厂方法的"集合版"。这个理解方式帮我记住了两者的关系。

5.3 适配器 vs 装饰器 vs 代理

这三个都是"包一层",结构相似度最高,也是选择题里最爱出的干扰组。

模式核心目的结构特征典型场景
适配器接口转换适配器实现目标接口,持有被适配者老接口对接新系统
装饰器动态加职责装饰器实现原接口,持有原接口加奶加糖、加日志
代理控制访问代理实现原接口,持有原接口权限校验、延迟加载

注意适配器的结构特征和其他两个不一样:适配器的被适配对象的接口和适配器实现的接口通常不是同一个,因为它的任务就是把 A 接口转成 B 接口。而装饰器和代理持有的是同一个接口。这个区别是我做题时的分水岭。

5.4 组合 vs 装饰器

这两个都会"持有同类型的对象",但组合持有的是一批(通常用 List),装饰器持有的只有一个。

组合模式的类图里,容器节点会有一个List<Component>或者数组,并且遍历它逐个调用子节点的方法,形成递归。装饰器只有一个Component成员,是单层包裹。看到 List 就是组合,看到单个引用就是装饰器,这个判断非常快。

5.5 命令 vs 策略

命令模式的关键词是"把请求封装成对象",它有一个很重要的副产品:支持撤销和排队。策略模式的关键词是"算法替换",它解决的是"怎么做"的问题,不涉及把操作记录下来。

在类图上看,命令模式通常有一个Command接口带execute()方法,还有一个Invoker负责调用,一个Receiver负责真正执行。策略模式没有Invoker和Receiver这种角色的划分,只有Context和Strategy。

5.6 模板方法 vs 策略

模板方法用继承,父类定义算法骨架,子类实现具体步骤。策略用组合,上下文持有一个策略对象。

考试里最容易混的是题干描述。如果题干说"算法的步骤是固定的,但某些步骤的具体实现可以不同",那是模板方法。如果题干说"整个算法都可以替换",那是策略。换句话说,模板方法替换的是"步骤",策略替换的是"整体"。

6. 上午题里设计模式的出题角度

上午题的设计模式考法和下午题完全不同,它不考代码,考的是理解和辨识。我把见过的出题角度归纳成三类,每一类的应对策略不一样。

6.1 给出场景选模式

这是最常见的类型。题干描述一个业务场景,问你应该采用哪种设计模式。比如"系统需要支持多种支付方式,且未来可能新增支付渠道",答案是策略模式;"一个对象状态改变时需要通知多个其他对象",答案是观察者模式;"需要为一个已有的类提供一个新接口以适应新的环境",答案是适配器模式。

这类题的关键是把题干里的"业务话术"翻译成"模式话术"。我总结了几个高频对应:

  • "多种算法/多种方式/可替换" → 策略
  • "一对多/通知/订阅" → 观察者
  • "固定流程/可变的步骤" → 模板方法
  • "不兼容/转换/复用已有类" → 适配器
  • "树形结构/部分整体" → 组合
  • "动态添加功能/层层包装" → 装饰器
  • "唯一实例/全局访问点" → 单例
  • "请求传递/多级审批" → 职责链

6.2 给出模式问意图

这类题直接问某个模式的意图或者定义。它会从教材原文里抠一句话,然后给四个选项让你选这个模式的名字,或者反过来问"以下哪个是策略模式的定义"。

应对方法就是前面那张核心意图表。但要注意,选项里经常混进"简单工厂"这个非 GoF 模式的干扰项。简单工厂严格来说不属于23种设计模式,它是工厂方法的一种简化变体,很多教材把它单独拿出来讲,但考试里如果问"23种设计模式包括以下哪个",简单工厂是不能选的。这个坑我踩过一次,印象很深。

6.3 给出类图判模式

这类题给一张简化类图,让你判断这是哪个模式。判断的抓手就是第4章讲的几个结构特征:接口数量、成员变量的类型和数量、继承关系。

我个人的判断流程是:先数接口,再看成员变量是不是接口类型,最后看是不是有 List。三个问题问完,基本能定位。

6.4 记忆锚点与口诀

我自己编过一套口诀,虽然有点土,但复习时确实管用:

  • 创建型五兄弟:工抽建原单(工厂、抽象工厂、建造者、原型、单例)
  • 结构型七兄弟:适桥组装外享代(适配器、桥接、组合、装饰、外观、享元、代理)
  • 行为型十一兄弟:责命解迭中备观状策模访(职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者)

这三个口诀背顺了,做"以下哪个不属于行为型模式"这种题就是秒答。

7. 我复习这一章踩过的坑与节奏安排

7.1 只背定义不写代码的坑

我第一遍复习就是这么干的,把23个模式的定义抄了一遍,觉得自己懂了。结果一到下午题,看到那段代码就完全傻眼——定义里的"定义一个用于创建对象的接口"和代码里的abstract class LoggerFactory之间,隔着一层转换的功夫,这层功夫只有自己写过一遍才有。

后来我的做法是:只挑十个高频模式,每个手敲一遍最小可运行版本。策略、观察者、工厂方法、抽象工厂、装饰器、代理、适配器、组合、模板方法、单例。每个不超过四十行,敲一遍十分钟,总共不到两个小时。这两个小时带来的收益,比背十遍定义都大。

7.2 把模式当成"万能药"的坑

有个细节容易在概念题里翻车:设计模式不是越多越好。题干如果描述一个非常简单的场景,而选项里有"使用抽象工厂模式"和"直接使用简单条件判断",正确的往往是后者。设计模式的引入是有成本的,类会增加、理解难度会上升。

考试里有一类"以下说法错误的是"的题,干扰项经常是"设计模式可以解决所有设计问题"或者"使用模式越多系统越好",这种明显是错的。记住:模式是为了应对变化,需求不变的地方用模式是画蛇添足。

7.3 最后两周的复习节奏

如果时间紧,我的建议是这样排:

阶段时间任务
第一轮3天过一遍23种模式定义,建立三分类记忆
第二轮2天手敲十个高频模式的最小实现
第三轮2天刷近五年下午题的设计模式大题
第四轮1天复习六大原则,做上午题专项
考前半天只看那张核心意图表和六组对比表

最后再分享一个小技巧,考前一天别再去看解释器、访问者这种冷门模式了,容易把已经记住的高频模式搅混。把精力放在那六组对比表上,考场上能一眼分清策略和状态,就赢了一大半。这一章的内容其实不多,难的是分类和辨识,而这两件事恰恰是可以通过短期密集训练解决的。我自己从完全懵到能稳定做对下午题那道大题,前后大概用了两周,其中真正有效的时间可能也就十来个小时。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询