一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
简介
模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。在软件工程中,它是一种软件设计模式,和C++模板没有关连。
正章
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 P289
特点
- 主导算法框架,并且保护这个算法 P288
- 最大化复用代码 P288
- 算法只存在于一个地方,容易修改 P288
- 专注算法本身,由子类提供完整的实现 P288
- 模板方法本身和内部具体操作解耦 P289
设计原则
好莱坞原则:低层组件别调用高层组件,让高层组件调用低层组件。 P296
优点
-
防止依赖腐败(依赖腐败会使用户难以弄懂系统的设计) P296 思考
还有哪些模式采用了好莱坞原则? P297 -
工厂方法、观察者
-
抽象工厂、外观、命令 思考
我们知道应该多用组合,少用继承。 sort() 模板方法的实现决定不使用继承, sort 方法被实现成一个静态的方法,在运行时和 Comparable 组合。这样的做法有何优缺点?你如何处置这个难题?难道 Java 数组让这一切变得特别麻烦吗? P305
优点
- 解耦了数组和对象,避免让对象数组继承数组
缺点
- 可排序数组的对象必须是 Comparable 的子类,比较逻辑没法动态改变
- 可以采用 Comparator 接口,该接口接受两个待比较的对象,返回比较结果;并在 sort 方法加上一个 Comparator 参数
难道 Java 数组让这一切变得特别麻烦吗?
-
Java 数组不是将这一切变得麻烦的主要原因,而是 Java 数组和对象数组的没有太多的联系,不能有太多耦合,所以不应该使用继承。(如果对象数组继承 Java 数组,则要求对象本身是 Comparable 的子类,极大地限制了数组的使用场景和范围) 思考 想一想另一个模式,它是模板方法的一种特殊情况,原语操作用来创建并返回对象。这是什么模式?
-
工厂方法模式、抽象工厂模式 所思所想
-
感觉模板方法就是在内部委托了多个策略,交给子类实现具体策略。其实平常写代码中,经常无意中会用到这种思想。比如在处理 excel 文件导入时,步骤相对固定,先进行各种校验,然后处理 excel 文件(根据请求的不同解析成不同的对象入库),最后返回导入结果。当时我就把处理 excel 文件这步抽出来,顺便使用了一下函数式接口。
public Result handleExcel(File excelFile, ExcelConsumer consumer) {
// 各种校验
boolean success = consumer.consume(excelFile);
// 构建结果封装对象,并返回
}