模版模式又叫模板方法模式,在一个方法中定义算法的骨架,而将一些步骤延迟到子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
一、介绍
模板方法模式是类的行为模式
准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。
模板模式涉及到三个角色:
- 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架;
- 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法;
- 客户角色:客户类提出使用具体类的请求;
二、示例
举个例子,以早上起床到上班所需要的操作为例,大致流程可以分为以下几步:穿衣服、刷牙、洗脸、吃早餐等。男生和女生的操作可能有些区别。
我们创建一个抽象的类,定义好大致的操作流程,如下:
1 |
|
因为男生和女生的行为不一样,我们分别创建两个具体类,如下:
1 |
|
1 |
|
创建一个客户端,实现如下:
1 |
|
输出结果:
1 |
|
当然,模版模式的玩法,还不仅仅只有这些,还可以在模版模式中使用挂钩(hook)。
什么是hook
呢?存在一个空实现的方法,我们称这种方法为hook
。子类可以视情况来决定是否要覆盖它。
还是以上面为例子,比如吃完早餐就要出门上班,选择什么交通工具呢?
抽象类新增方法hook()
,内容如下:
1 |
|
男生具体实现类,重写hook()
方法,内容如下:
1 |
|
运行测试类,男生具体实现类,输出结果:
1 |
|
当然,还有其他的玩法,比如女生洗完脸之后,可能需要化妆,我们再次将抽象类进行处理,内容如下:
1 |
|
女生具体实现类,重写isMakeUp()
方法,内容如下:
1 |
|
运行测试类,女生具体实现类,输出结果:
1 |
|
三、应用
模版设计模式,应用非常广泛,比如javaEE中的servlet,当我们每创建一个servlet的时候,都会继承HttpServlet
,其实HttpServlet
已经为我们提供一套操作流程,我们只需要重写里面的方法即可!
HttpServlet 的部分源码如下:
1 |
|
自定义一个 HelloWorld 的 Servlet 类,如下:
1 |
|
四、总结
模版模式有着许多的优点:
1、模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码;
2、子类实现算法的某些细节,有助于算法的扩展;
3、通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合开放-封闭原则
;
也有些缺点: 1、每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象
如果某些类有一些共同的行为,可以使用模版设计模式,创建一个抽象类,将共同的行为定义在抽象类中,可以有效的减少子类重复的代码。