模板方法模式
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤
如何理解模板模式
在我们的认识中,模板就是一些约定俗成的东西,是一些自然而然的事物规律。当我们想要解决一些具有模板规律的事情的时候,手中的模板就是一个个整齐待发的磨具,能够轻松进行重复制造、生产。由此想了想,生活中哪些事情满足模板模式的规律:
- 制茶,制茶是一个很有讲究的学问。制造茶的流程总是相对固定的。采青-> 萎凋->发酵-> 杀青 -> 揉捻 -> 干燥 -> 初制茶。每个工坊的制作工艺有所差别,有些工坊的手工揉捻做的比较好,有些工坊的萎凋做的比较有特点,所以生产出来的茶叶有所区别。但是他们的总体流程是相对差不多的,都遵循相同的制作模板。
- 造车,车的总体功能差不多, 能够启动、停止,能够鸣笛、跑路。但是不同型号的车是有所差异的。有些车是手动挡,有些是自动挡。
我们可以根据这类食物的规律总结一下特点:
- 具有一个抽象的模板,这个模板决定了这类事物的总体流程规律(父类抽象模板)
- 不同的事物虽然具有共同的抽象模板,但是彼此有着个性化的差异(个性化子类)
- 子类的个性化特点能够重新定义整个事物的最终呈现结构,就好比不同的茶叶工坊的制作工艺的差别会导致这个茶叶具有不同销量和名声。不同型号的车会导致车具有不同的价格和市场。
程序是现实世界的抽象,模板模式的类可以总结如下:
抽象模板
- 基本方法
子类的个性化方法,由子类去实现,如制茶过程中每一个环节(发酵...)
- 模板方法
对基本方法的调度,已完成固定的逻辑。如制茶这样的模板方法就是将制茶每个环节的调度,完成造茶这么一个逻辑。
注意:
- 基本方法尽量设计成protected类型,符合迪米特法则,若非必要,尽量不要扩大父类的访问权限。
- 模板方法一般设计成final类型,不要被覆写
为什么要用模板模式
- 封装不变部分,扩展可变部分
不变的流程规律由父类来实现,而可变的每个环节由子类来控制。
提取公共部分代码,便于维护
行为由父类控制、子类实现
基本方法由子类实现,子类可以通过扩展类来增加相应功能,符合开闭原则。
模板模式实现
模板模式也有缺陷
四思维方式与以往有所不同,不好理解。
常规思路:
抽象类->最抽象、最一般的事物属性和方法
具体类->具体的事物属性和方法
模板模式思路:
抽象类->定义部分抽象方法
实现类->子类的执行结果对父类结构产生影响
总结一下
模板模式的扩展--钩子函数的应用
由子类的一个方法返回值来决定公共部分的执行结果
引申
父类怎么调用子类的方法
- 子类传递到父类的有参构造中
- 反射
- 父类调用子类的静态方法
其实模板模式就间接的实现了父类依赖子类的场景
- 父类建立框架->子类重写父类 -> 调用父类继承方法-> 影响父类结果