设计模式阅读笔记
说明:
刘伟
所著《设计模式的艺术之道(软件开发人员内功修炼之道)》
一书的阅读笔记至此就全部更新完成,个人感觉这本书讲的不错,有兴趣推荐阅读,详细内容也可以看看此书作者的博客https://blog.csdn.net/LoveLion/article/details/17517213
- 此外也整理在 侠客岛 站点 设计模式专题
关于金庸小说中到底是招式重要还是内功重要的争论从未停止,我们在这里并不分析张无忌的九阳神功和令狐冲的独孤九剑到底哪个更厉害,但我想每个江湖高手梦寐以求的应该是既有淋漓的招式又有深厚的内功。
看到这里大家可能会产生疑问了?搞什么,讨论什么招式与内功,我只是个软件工程师。别急,正因为你是软件工程师我才跟你谈这个,因为我们的软件开发技术也包括一些招式和内功:Java
、Python
、Golang
等编程语言,微服务、中间件、大数据、人工智能等开发方向, Spring Cloud
、Flink
、Spark
、PyTorch
、K8s
等框架技术,所有这些我们都可以认为是招式;而数据结构、算法、设计模式、重构、软件工程、操作系统、网络等则为内功。招式可以很快学会,但是内功的修炼需要更长的时间。我想每一位软件开发人员也都希望成为一名兼具淋漓招式和深厚内功的“上乘”软件工程师,而对设计模式的学习与领悟将会让你“内功”大增,再结合你日益纯熟的“招式”,你的软件开发“功力”一定会达到一个新的境界。既然这样,还等什么,赶快行动吧。下面就让我们正式踏上神奇而又美妙的设计模式之旅。
设计模式是什么
站在别人的肩膀上,我们会看得更远。
设计模式的出现可以让我们站在前人的肩膀上,通过一些成熟的设计方案来指导新项目的开发和设计,以便于我们开发出具有更好的灵活性和可扩展性,也更易于复用的软件系统。
设计模式的一般定义如下:
设计模式(
Design Pattern)
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。
与很多软件工程技术一样,模式起源于建筑领域。
在经典著作《建筑的永恒之道》中,有关于模式的定义:
A pattern is a successful or efficient solution to a recurring problem within a context.
也就是说 模式是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案。
每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的成功的解决方案,无须再重复相同的工作。
最早将模式的思想引入软件工程方法学的是1991-1992年以“四人组(Gang of Four
,简称GoF
,分别是Erich Gamma
, Richard Helm
, Ralph Johnson
和John Vlissides
)”自称的四位著名软件工程学者,他们在1994年归纳发表了23种在软件开发中使用频率较高的设计模式,旨在用模式来统一沟通面向对象方法在分析、设计和实现间的鸿沟。
GoF
将模式的概念引入软件工程领域,这标志着软件模式的诞生。软件模式(Software Patterns
)是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。
软件模式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件开发生命周期的每一个阶段都存在着一些被认同的模式。
在软件模式中,设计模式是研究最为深入的分支,设计模式用于在特定的条件下为一些重复出现的软件设计问题提供合理的、有效的解决方案,它融合了众多专家的设计经验,已经在成千上万的软件中得以应用。
设计模式的分类
虽然GoF
设计模式只有23
个,但是它们各具特色,每个模式都为某一个可重复的设计问题提供了一套解决方案。
根据用途来分,设计模式可分为:
- 创建型(
Creational
):主要用于描述如何创建对象 - 结构型(
Structural
):主要用于描述如何实现类或对象的组合 - 行为型(
Behavioral
):主要用于描述类或对象怎样交互以及怎样分配职责
在GoF
23种设计模式中包含5
种创建型设计模式、7
种结构型设计模式和11
种行为型设计模式。
值得一提的是,有一个设计模式虽然不属于GoF
23种设计模式,但一般在介绍设计模式时都会对它进行说明,它就是简单工厂模式
,也许是太“简单”了,GoF
并没有把它写到那本经典著作中,不过现在大部分的设计模式书籍都会对它进行专门的介绍。
创建型模式
模式名称 | 学习难度 | 使用频率 |
---|---|---|
单例模式(Singleton Pattern)——确保对象的唯一性 | ★☆☆☆☆ | ★★★★☆ |
简单工厂模式(Simple Factory Pattern) | ★★☆☆☆ | ★★★☆☆ |
工厂方法模式(Factory Method Pattern) | ★★☆☆☆ | ★★★★★ |
抽象工厂模式(Abstract Factory Pattern) | ★★★★☆ | ★★★★★ |
原型模式(Prototype Pattern)——对象的克隆 | ★★★☆☆ | ★★★☆☆ |
建造者模式(Builder Pattern)——复杂对象的组装与创建 | ★★★★☆ | ★★☆☆☆ |
结构型模式
模式名称 | 学习难度 | 使用频率 |
---|---|---|
适配器模式(Adapter Pattern)——不兼容结构的协调 | ★★☆☆☆ | ★★★★☆ |
桥接模式(Bridge Pattern)——处理多维度变化 | ★★★☆☆ | ★★★☆☆ |
组合模式(Composite Pattern)——树形结构的处理 | ★★★☆☆ | ★★★★☆ |
装饰模式(Decorator Pattern)——扩展系统功能 | ★★★☆☆ | ★★★☆☆ |
外观模式(Facade Pattern)——提供统一的入口 | ★☆☆☆☆ | ★★★★★ |
享元模式(Flyweight Pattern)——实现对象的复用 | ★★★★☆ | ★☆☆☆☆ |
代理模式(Proxy Pattern)——对象的间接访问 | ★★★☆☆ | ★★★★☆ |
行为型模式
模式名称 | 学习难度 | 使用频率 |
---|---|---|
职责链模式(Chain of Responsibility Pattern)——请求的链式处理 | ★★★☆☆ | ★★☆☆☆ |
命令模式(Command Pattern)——请求发送者与接收者解耦 | ★★★☆☆ | ★★★★☆ |
解释器模式(Interpreter Pattern)——自定义语言的实现 | ★★★★★ | ★☆☆☆☆ |
迭代器模式(Iterator Pattern)——遍历聚合对象中的元素 | ★★★☆☆ | ★★★★★ |
中介者模式(Mediator Pattern)——协调多个对象之间的交互 | ★★★☆☆ | ★★☆☆☆ |
备忘录模式(Memento Pattern)——撤销功能的实现 | ★★☆☆☆ | ★★☆☆☆ |
观察者模式(Observer Pattern)——对象间的联动 | ★★★☆☆ | ★★★★★ |
状态模式(State Pattern)——处理对象的多种状态及其相互转换 | ★★★☆☆ | ★★★☆☆ |
策略模式(Strategy Pattern)——算法的封装与切换 | ★☆☆☆☆ | ★★★★☆ |
模板方法模式(Template Method Pattern)——复杂流程步骤的设计 | ★★☆☆☆ | ★★★☆☆ |
访问者模式(Visitor Pattern)——操作复杂对象结构 | ★★★★☆ | ★☆☆☆☆ |
此外,根据某个模式主要是用于处理类之间的关系还是对象之间的关系,设计模式还可以分为:
- 类模式:处理类之间的关系
- 对象模式:处理对象之间的关系
我们经常将两种分类方式结合使用,如单例模式是对象创建型模式,模板方法模式是类行为型模式。
学习建议
补充: 面向对象设计原则
-
掌握设计模式并不是件很难的事情,关键在于多思考,多实践,不要听到人家说懂几个设计模式就很“牛”,只要用心学习,设计模式也就那么回事,你也可以很“牛”的,一定要有信心。
-
在学习每一个设计模式时至少应该掌握如下几点:这个设计模式的意图是什么,它要解决一个什么问题,什么时候可以使用它;它是如何解决的,掌握它的结构图,记住它的关键代码;能够想到至少两个它的应用实例,一个生活中的,一个软件中的;这个模式的优缺点是什么,在使用时要注意什么。当你能够回答上述所有问题时,恭喜你,你了解一个设计模式了,至于掌握它,那就在开发中去使用吧,用多了你自然就掌握了。
-
“如果想体验一下运用模式的感觉,那么最好的方法就是运用它们”。正如在本章最开始所说的,设计模式是“内功心法”,它还是要与“实战招式”相结合才能够相得益彰。学习设计模式的目的在于应用,如果不懂如何使用一个设计模式,而只是学过,能够说出它的用途,绘制它的结构,充其量也只能说你了解这个模式,严格一点说:不会在开发中灵活运用一个模式基本上等于没学。所以一定要做到:少说多做。
-
千万不要滥用模式,不要试图在一个系统中用上所有的模式,也许有这样的系统,但至少目前我没有碰到过。每个模式都有自己的适用场景,不能为了使用模式而使用模式?滥用模式不如不用模式,因为滥用的结果得不到“艺术品”一样的软件,很有可能是一堆垃圾代码。
-
如果将设计模式比喻成“三十六计”,那么每一个模式都是一种计策,它为解决某一类问题而诞生,不管这个设计模式的难度如何,使用频率高不高,我建议大家都应该好好学学,多学一个模式也就意味着你多了“一计”,说不定什么时候一不小心就用上了,。因此,模式学习之路上要不怕困难,勇于挑战,有的模式虽然难一点,但反复琢磨,反复研读,应该还是能够征服的。
-
设计模式的“上乘”境界:“手中无模式,心中有模式”。模式使用的最高境界是你已经不知道具体某个设计模式的定义和结构了,但你会灵活自如地选择一种设计方案【其实就是某个设计模式】来解决某个问题,设计模式已经成为你开发技能的一部分,能够手到擒来,“内功”与“招式”已浑然一体,要达到这个境界并不是看完某本书或者开发一两个项目就能够实现的,它需要不断沉淀与积累,所以,对模式的学习不要急于求成。
-
最后一点来自
GoF
已故成员、我个人最尊敬和崇拜的软件工程大师之一John Vlissides
的著作《设计模式沉思录》(Pattern Hatching Design Patterns Applied
):模式从不保证任何东西,它不能保证你一定能够做出可复用的软件,提高你的生产率,更不能保证世界和平。模式并不能替代人来完成软件系统的创造,它们只不过会给那些缺乏经验但却具备才能和创造力的人带来希望。