极客时间《架构师训练营》第三章学习笔记
设计模式
什么是设计模式?设计模式是对软件设计中反复出现的各种问题所提供的通用解决方案。设计模式最早启发于建筑设计领域,并由 GOF“四人帮”出版《设计模式:可复用面向对象软件的基础》一书得名。该书只提出了 23 种最经典的模式,但是经过软件行业多年发展现已有一百多种设计模式得到应用。
设计模式分类多种多样,比较经典的大类有如下几种:
- 创建型模式:如工厂方法、单例模式、原型模式
- 结构型模式:如适配器模式、组合模式、外观模式
- 行为型模式:如模版方法、观察者模式
本文就笼统地介绍一些老师上课时通过案例提到过的几个模式:
简单工厂模式
简单工厂,顾名思义就是用“工厂”去生产一类“产品”。如下所示,Client 用到的两个产品(Onion 和 Garlic)就由 SimpleFactory 产出:

问题来了,为什么要找个第三方“工厂”来给 Client 提供产品呢?为什么不直接 new ?这就涉及到上一章的知识——依赖倒置原则:
高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象
简单工厂使得 Client 只依赖底层模块的抽象——Vegetable,不需要依赖具体的实现类——Onion 和 Garlic,解耦了高层模块和低层模块。工厂模式的最大优点就是屏蔽产品的具体实现,调用者只需依赖产品的接口。当然它也有自己的问题,产品种类可能有成千上万,如果都是依靠同一个工厂生产,那么必然会使得工厂代码及其庞大。为了解决这个弊端,像 Spring 这样的框架就让工厂读取特定的配置文件,通过映射关系找到具体的产品实现类。
单例模式
单例模式比较容易理解:单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。

如上图所示,我加了个标签,示例代码里只有当首次调用 getInstance
方法时才初始化单例,这个技巧又称为“惰性初始化模式”。惰性初始是一种拖延战术。在第一次需求出现以前,延迟创建物件、计算值或其它昂贵的程序,以期提高应用程序的启动速度。命题作业第一题我就用了惰性初始化实现了单例模式。
适配器模式
适配器模式将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。

Java 中经典的案例现场:asList 适配了 array 和 collection 两种 API。
String a[] = new String[]{"abc","klm","xyz","pqr"};
List<String> list = Arrays.asList(a);
模版方法模式
模板模式:一个抽象类公开定义了执行它方法的模板。它的子类可以按需重写方法实现,但调用将以抽象类中定义的顺序进行。

我自己是 Vue 前端开发,模版方法每天都在使用。下面 Vue 文件里的 Option 方法(data
,computed
),以及生命周期钩子(mounted
,created
)就是模版方法里的钩子:
// sample.vue
export default {
data() {},
computed() {},
created() {},
mounted() {}
}
策略模式
策略模式定义了算法族,分别封装起来,使得一个类的行为或其算法可以在运行时更改。

策略模式我在写前端的时候用到过;就是在表单验证时,根据后端返回的错误类型,动态替换 Message 显示。虽然前端代码很少写 class 啦,一般多用函数式类型,但是思想是一脉相承的:
组合模式
组合模式在命题作业里已经提到过了,图就直接拿过来了,这里不细说了。

装饰器模式
装饰器模式又名包装模式,允许向一个现有的对象添加新的功能,同时又不改变其结构。

说起装饰器模式,印象还是挺深刻的。我记得在学校学 java 时,一知半解;每次要读取文件时都会写下面这样的套路代码;当时觉得很惊奇,为什么能嵌套这么多层 new
?后来还是看了《Head First 设计模式》才恍然大悟,这个是装饰器模式的经典设计。
InputStream input = new BufferedInputStream(
new FileInputStream(
new File("a.txt")
));
小结
这期老师借用 Sorter 和 Junit 两个案例讲解了好几个设计模式。其实我曾经读过很多本设计模式的书籍,有《Head First》、《设计模式之禅》、《敏捷软件开发(原则模式与实践)》、《Javascript 设计模式》、《图解设计模式》等等,每每读到精彩之处都有一种豁然开朗之感。后来我转前端开发了,多用函数式编程,OOP 设计模式逐渐淡忘了。这次又回顾了一遍,顺便画了一手 UML,抽象设计似乎又熟悉了一分。
现在工作中流行所谓的“敏捷开发”,几乎不写文档,更不做设计。很多领导只做工作分配,几乎不参与代码;底层小职员开发“随心所欲”、团队合作只靠“口口相传”。我自己工作也五年多了,说实在还是很缺乏那种宏观的设计概念,之后打算放下心来多画画设计图,也许之前加班的原因还是自己思考地太少了。
网友评论