作者: andylin02
学习章节: 《Head First设计模式》概览与学习指南
关键词:设计模式, 面向对象, 策略模式, 观察者模式, 装饰者模式, 设计原则, Java
《Head First设计模式》到底讲了什么?新手怎么学才不会从入门到放弃
大家好,我是 andylin02。如果你刚翻开《Head First设计模式》这本书,可能会被它花哨的排版、满篇的图片和看似零散的故事搞得一脸懵。别急,这正是 Head First 系列的魔力——它用大量视觉化、故事化的方式,把枯燥的设计模式讲活。今天这篇长文,我带你从零开始,搞明白这本书的全部脉络、你能学到什么、需要准备什么,以及给出可以直接参考的学习笔记、源码和图解。文末还会预告第一章“策略模式”的精彩内容,让我们一起开启设计模式之旅。
一、这本书到底讲了什么?
想象一下,你刚入职一家游戏公司,老板让你做一款“鸭子模拟器”。你想都没想,设计了一个 Duck 超类,让所有鸭子继承它。一切都很美好,直到老板说:“我们需要鸭子会飞”。你轻松地在 Duck 里加了 fly() 方法——结果,橡皮鸭子也在屏幕上扑棱扑棱飞了起来,全场爆笑。
这就是《Head First设计模式》贯穿始终的核心矛盾:软件唯一不变的就是变化。怎么让代码在需求变动时还能优雅地扩展,而不是牵一发动全身?这本书用一个个类似“鸭子困境”的故事,引出 23个经典设计模式 中最常用、最核心的十几个模式,并让你反复体会背后那些永恒的设计原则。
全书可以分成以下几大块:
- 设计模式入门与原则(第1章):策略模式,正式带你理解“把变化的部分封装起来”。
- 观察者与装饰者(第2-3章):让对象之间松耦合通信,以及运行时动态地扩展职责。
- 工厂模式家族(第4章):把对象创建的过程抽象出来,让代码不再硬依赖具体类。
- 单例与命令模式(第5-6章):控制唯一实例,以及把请求封装成对象,支持撤销、队列等。
- 适配器与外观模式(第7章):把不兼容的接口转换得能一起工作,以及提供简化接口。
- 模板方法与迭代器组合模式(第8-9章):定义算法骨架,以及如何优雅地遍历集合。
- 状态模式(第10章):让对象的行为随着内部状态改变而改变。
- 代理模式(第11章):给另一个对象提供一个替身,以控制访问。
- 复合模式与实战(第12章):MVC 架构就是多种模式的组合运用。
- 更多模式与设计原则总结(第13-14章):介绍剩余模式,回归设计原则本身。
书中每个模式都采用固定的讲解结构:问题场景 → 直观解决方案的失败 → 设计原则 → 模式正式定义 → 类图 → 代码实现 → 实际应用案例。这种结构很适合初学者跟着思考,而不是被动接受。
二、学好这本书,你能学到哪些关键知识?
如果你认真啃完这本书并手写了所有代码,你将收获一把衡量代码好坏的内在标尺。具体来说:
面向对象设计的九大原则
- 封装变化
- 针对接口编程,而不是针对实现
- 多用组合,少用继承
- 为交互对象之间的松耦合设计而努力
- 对扩展开放,对修改关闭(开闭原则)
- 依赖倒置:依赖抽象,不要依赖具体类
- 最少知识原则:只和你的密友谈话
- 好莱坞原则:别调用我们,我们会调用你
- 单一职责:一个类应该只有一个引起变化的原因
这些原则比模式本身更重要,它们是模式背后的“心法”。
十几个核心设计模式:策略、观察者、装饰者、工厂方法、抽象工厂、单例、命令、适配器、外观、模板方法、迭代器、组合、状态、代理、复合模式等。掌握它们,你就能看懂大部分优秀框架的源码(比如 Spring 里随处可见的模板方法、策略、代理模式)。
模式分类的全局视野:理解创建型、结构型、行为型三大分类,能够根据问题类型快速锁定可能的模式方向。
真正的面向对象编程思维:不只是会写 class 和 extends,而是懂得如何给对象分配职责,设计弹性的体系。
阅读和绘制 UML 类图的能力,这是开发者之间交流设计思想的通用语言。
三、我需要具备什么基础能力?要准备什么?
这本书对初学者非常友好,但并不意味着零基础就能直接上手。你需要:
- Java 基础:能熟练定义类和接口,理解继承、多态、抽象类、方法重写。因为所有示例代码都是 Java,至少要能看懂并运行。
- 基本的 IDE 使用:推荐 IntelliJ IDEA 或 Eclipse,能新建项目、写类、运行 main 方法。
- 一颗愿意深究“为什么”的心:如果只满足于跑通代码,你会错过这本书 80% 的价值。
准备工作清单:
四、有什么注意事项?
- 不要追求一次全懂:尤其工厂模式那章知识点密集,可以分两天消化。反复阅读,每次都有新感悟。
- 模式不是银弹:别学完一个模式就到处套,为了模式而模式会让代码更难懂。简单的需求不需要复杂的设计。
- 优先掌握原则,而非死记类图:类图你可以随时查,但原则是内化的思维习惯。
- 结合生活类比理解:比如观察者模式就是“报纸订阅”,策略模式就是“选择不同的交通工具上班”。全书充满了这样的比喻,善于利用它们。
- 第12章 MVC 是集大成者:学完前面所有模式再去看 MVC,你会恍然大悟,原来这些模式可以这样组合。
五、详细学习文档与读书笔记
为了帮你建立起清晰的知识框架,我整理了一份超详细的学习导图。首先,让我们看看这十几个模式在整个设计模式版图中的位置:
#mermaid-svg-qNA5k9PlzVq2Pxhn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qNA5k9PlzVq2Pxhn .error-icon{fill:#552222;}#mermaid-svg-qNA5k9PlzVq2Pxhn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qNA5k9PlzVq2Pxhn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .marker.cross{stroke:#333333;}#mermaid-svg-qNA5k9PlzVq2Pxhn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qNA5k9PlzVq2Pxhn p{margin:0;}#mermaid-svg-qNA5k9PlzVq2Pxhn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster-label text{fill:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster-label span{color:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster-label span p{background-color:transparent;}#mermaid-svg-qNA5k9PlzVq2Pxhn .label text,#mermaid-svg-qNA5k9PlzVq2Pxhn span{fill:#333;color:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .node rect,#mermaid-svg-qNA5k9PlzVq2Pxhn .node circle,#mermaid-svg-qNA5k9PlzVq2Pxhn .node ellipse,#mermaid-svg-qNA5k9PlzVq2Pxhn .node polygon,#mermaid-svg-qNA5k9PlzVq2Pxhn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .rough-node .label text,#mermaid-svg-qNA5k9PlzVq2Pxhn .node .label text,#mermaid-svg-qNA5k9PlzVq2Pxhn .image-shape .label,#mermaid-svg-qNA5k9PlzVq2Pxhn .icon-shape .label{text-anchor:middle;}#mermaid-svg-qNA5k9PlzVq2Pxhn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .rough-node .label,#mermaid-svg-qNA5k9PlzVq2Pxhn .node .label,#mermaid-svg-qNA5k9PlzVq2Pxhn .image-shape .label,#mermaid-svg-qNA5k9PlzVq2Pxhn .icon-shape .label{text-align:center;}#mermaid-svg-qNA5k9PlzVq2Pxhn .node.clickable{cursor:pointer;}#mermaid-svg-qNA5k9PlzVq2Pxhn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .arrowheadPath{fill:#333333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qNA5k9PlzVq2Pxhn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qNA5k9PlzVq2Pxhn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qNA5k9PlzVq2Pxhn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster text{fill:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn .cluster span{color:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qNA5k9PlzVq2Pxhn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qNA5k9PlzVq2Pxhn rect.text{fill:none;stroke-width:0;}#mermaid-svg-qNA5k9PlzVq2Pxhn .icon-shape,#mermaid-svg-qNA5k9PlzVq2Pxhn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qNA5k9PlzVq2Pxhn .icon-shape p,#mermaid-svg-qNA5k9PlzVq2Pxhn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qNA5k9PlzVq2Pxhn .icon-shape .label rect,#mermaid-svg-qNA5k9PlzVq2Pxhn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qNA5k9PlzVq2Pxhn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qNA5k9PlzVq2Pxhn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qNA5k9PlzVq2Pxhn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
设计模式
创建型
结构型
行为型
单例模式
工厂方法模式
抽象工厂模式
适配器模式
外观模式
装饰者模式
代理模式
策略模式
观察者模式
命令模式
模板方法模式
迭代器模式
组合模式
状态模式
学习路线建议(按章节顺序):
下面我以第一章的策略模式为例,给出完整的 UML 图和源代码,让你提前感受一下书中的学习方式。
策略模式:从“鸭子困境”学到设计原则
故事回顾:Joe 的鸭子模拟器里,所有鸭子都会叫、会游泳,但老板不断加需求:有的会飞,有的不会,有的吱吱叫,有的呱呱叫。如果在 Duck 超类里直接实现 fly(),所有子类都继承会飞的行为——橡皮鸭也会飞。如果用接口 Flyable,每个会飞的子类自己实现,导致大量重复代码。怎么办?
设计原则登场:
- 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
变化的是“飞行行为”和“呱呱叫行为”,我们把它们分别封装成独立的接口族。 - 针对接口编程,而不是针对实现。
鸭子类不关心具体怎么飞,只依赖 FlyBehavior 接口。 - 多用组合,少用继承。
每个鸭子“有一个”飞行行为和一个呱呱叫行为,而不是“是一个”固定的飞行器。
策略模式定义:定义了一系列算法,把它们一个个封装起来,并且使它们可以互相替换。策略模式让算法的变化独立于使用它的客户。
UML 类图:
#mermaid-svg-1jHVYCPNRU8oLrJB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1jHVYCPNRU8oLrJB .error-icon{fill:#552222;}#mermaid-svg-1jHVYCPNRU8oLrJB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1jHVYCPNRU8oLrJB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1jHVYCPNRU8oLrJB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1jHVYCPNRU8oLrJB .marker.cross{stroke:#333333;}#mermaid-svg-1jHVYCPNRU8oLrJB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1jHVYCPNRU8oLrJB p{margin:0;}#mermaid-svg-1jHVYCPNRU8oLrJB g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-1jHVYCPNRU8oLrJB g.classGroup text .title{font-weight:bolder;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster-label text{fill:#333;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster-label span{color:#333;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster-label span p{background-color:transparent;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster text{fill:#333;}#mermaid-svg-1jHVYCPNRU8oLrJB .cluster span{color:#333;}#mermaid-svg-1jHVYCPNRU8oLrJB .nodeLabel,#mermaid-svg-1jHVYCPNRU8oLrJB .edgeLabel{color:#131300;}#mermaid-svg-1jHVYCPNRU8oLrJB .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-1jHVYCPNRU8oLrJB .label text{fill:#131300;}#mermaid-svg-1jHVYCPNRU8oLrJB .labelBkg{background:#ECECFF;}#mermaid-svg-1jHVYCPNRU8oLrJB .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-1jHVYCPNRU8oLrJB .classTitle{font-weight:bolder;}#mermaid-svg-1jHVYCPNRU8oLrJB .node rect,#mermaid-svg-1jHVYCPNRU8oLrJB .node circle,#mermaid-svg-1jHVYCPNRU8oLrJB .node ellipse,#mermaid-svg-1jHVYCPNRU8oLrJB .node polygon,#mermaid-svg-1jHVYCPNRU8oLrJB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1jHVYCPNRU8oLrJB .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB g.clickable{cursor:pointer;}#mermaid-svg-1jHVYCPNRU8oLrJB g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-1jHVYCPNRU8oLrJB g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-1jHVYCPNRU8oLrJB .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-1jHVYCPNRU8oLrJB .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-1jHVYCPNRU8oLrJB .dashed-line{stroke-dasharray:3;}#mermaid-svg-1jHVYCPNRU8oLrJB .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-1jHVYCPNRU8oLrJB #compositionStart,#mermaid-svg-1jHVYCPNRU8oLrJB .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #compositionEnd,#mermaid-svg-1jHVYCPNRU8oLrJB .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #dependencyStart,#mermaid-svg-1jHVYCPNRU8oLrJB .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #dependencyStart,#mermaid-svg-1jHVYCPNRU8oLrJB .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #extensionStart,#mermaid-svg-1jHVYCPNRU8oLrJB .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #extensionEnd,#mermaid-svg-1jHVYCPNRU8oLrJB .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #aggregationStart,#mermaid-svg-1jHVYCPNRU8oLrJB .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #aggregationEnd,#mermaid-svg-1jHVYCPNRU8oLrJB .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #lollipopStart,#mermaid-svg-1jHVYCPNRU8oLrJB .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB #lollipopEnd,#mermaid-svg-1jHVYCPNRU8oLrJB .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1jHVYCPNRU8oLrJB .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-1jHVYCPNRU8oLrJB .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1jHVYCPNRU8oLrJB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1jHVYCPNRU8oLrJB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1jHVYCPNRU8oLrJB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
«abstract»
Duck
FlyBehavior flyBehavior
QuackBehavior quackBehavior
+performFly()
+performQuack()
+swim()
+display()
+setFlyBehavior(FlyBehavior fb)
+setQuackBehavior(QuackBehavior qb)
MallardDuck
+display()
RedheadDuck
+display()
RubberDuck
+display()
«interface»
FlyBehavior
+fly()
FlyWithWings
+fly()
FlyNoWay
+fly()
«interface»
QuackBehavior
+quack()
Quack
+quack()
Squeak
+quack()
MuteQuack
+quack()
完整源码:
// ========== 飞行行为接口与实现 ==========
public interface FlyBehavior {
void fly();
}
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying with wings!");
}
}
public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("I can't fly.");
}
}
// ========== 呱呱叫行为接口与实现 ==========
public interface QuackBehavior {
void quack();
}
public class Quack implements QuackBehavior {
public void quack() {
System.out.println("Quack! Quack!");
}
}
public class Squeak implements QuackBehavior {
public void quack() {
System.out.println("Squeak! Squeak!");
}
}
public class MuteQuack implements QuackBehavior {
public void quack() {
System.out.println("<< Silence >>");
}
}
// ========== 鸭子抽象类 ==========
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
public abstract void display();
// 动态设定行为,增加弹性
public void setFlyBehavior(FlyBehavior fb) {
this.flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
this.quackBehavior = qb;
}
}
// ========== 具体鸭子子类 ==========
public class MallardDuck extends Duck {
public MallardDuck() {
flyBehavior = new FlyWithWings();
quackBehavior = new Quack();
}
public void display() {
System.out.println("I'm a real Mallard duck");
}
}
public class RubberDuck extends Duck {
public RubberDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Squeak();
}
public void display() {
System.out.println("I'm a rubber duckie");
}
}
// ========== 测试运行 ==========
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.display();
mallard.performQuack();
mallard.performFly();
Duck rubber = new RubberDuck();
rubber.display();
rubber.performQuack();
rubber.performFly();
// 动态改变行为——这才是策略模式的威力
rubber.setFlyBehavior(new FlyWithWings());
rubber.performFly(); // 哇!橡皮鸭装上火箭引擎飞起来了!
}
}
运行这段代码,你会直观地看到:我们通过组合行为对象,轻松搭建出不同行为的鸭子,并且能够在运行时动态切换行为。这就为后续的观察者模式、装饰者模式打下了坚实的思维基础。
全书模式速查笔记(简要)
| 策略模式 | 封装算法,使其可互换 | 封装变化,多用组合 |
| 观察者模式 | 主题状态改变时通知所有观察者 | 松耦合,推/拉数据 |
| 装饰者模式 | 动态给对象添加职责 | 对扩展开放,对修改关闭 |
| 工厂方法 | 定义创建对象的接口,让子类决定实例化哪个类 | 依赖倒置,针对抽象编程 |
| 抽象工厂 | 创建一系列相关对象,而不指定具体类 | 依赖倒置 |
| 单例模式 | 确保一个类只有一个实例 | 全局访问点,懒/饿汉加载 |
| 命令模式 | 把请求封装为对象 | 解耦调用者与执行者,支持撤销 |
| 适配器模式 | 把不兼容的接口转换为客户端期望的接口 | 转换接口,兼容旧代码 |
| 外观模式 | 提供统一的高层接口,简化子系统使用 | 最少知识原则 |
| 模板方法 | 在方法中定义算法骨架,将部分步骤延迟到子类 | 好莱坞原则 |
| 迭代器模式 | 提供顺序访问聚合对象元素的方法,而不暴露内部表示 | 单一职责,遍历与集合分离 |
| 组合模式 | 将对象组合成树形结构以表示“部分-整体”层次 | 统一处理单个对象和组合对象 |
| 状态模式 | 对象内部状态改变时改变其行为 | 把状态封装为独立类 |
| 代理模式 | 给另一个对象提供一个替身,控制对它的访问 | 控制访问,延迟加载 |
你可以把它打印出来,贴在学习桌前,每学完一个模式就自己填上实例和理解,效果极佳。
六、总结
《Head First设计模式》绝对不是一本让你“读完就忘”的教科书,它是一本训练营手册。它逼迫你不断思考软件变化之源,并通过手把手的故事和代码,把设计原则烙进你的思维里。
从策略模式起,你就开始学会“把变化的地方揪出来关进笼子里”。后续每一个模式,都是在不同场景下对这个核心思想的进一步演绎。好好跟着书中的节奏走,别跳步,你会发现:六个月后,当你回看自己过去写的“一锅粥”代码时,会不由自主地皱起眉头,并脑海中自动浮现出一个合适的模式来重构它。那个时刻,你就真正入门了。
七、下篇预告:第一章·策略模式深度剖析
今天我们整体梳理了《Head First设计模式》的全貌,并给出了策略模式的初体验。下一篇文章,我将带你正式走进第一章——策略模式,我会逐句讲解鸭子模拟器的开发历程、每一个设计决策背后的得失,以及如何将策略模式应用到真实的项目(比如支付系统中的不同支付策略)。还会带来更多变体练习和课后思考。敬请期待!
本文为个人学习笔记,仅用于知识分享。如有错误,欢迎指正。
👍🏻 点赞 + 收藏 + 分享,让更多开发者看到这篇深度解析!❤️ 如果觉得有用,请给个赞支持一下作者!

