模板方法模式

介绍

在面向对象编程的过程中,通常会遇到一个问题,我们知道一个算法的所需要的关键的步骤,并且确定了这些步骤的执行的顺序,但是某些步骤的具体实现是未知的,或者说是某些步骤的实现会随着环境的变化而变化,例如,执行程序员的流程如下:

  • 检查代码的正确性
  • 链接相关的类库
  • 编译相关的代码
  • 执行程序

对于不同的程序而言上述的四个步骤是不一样的,但是他们的执行流程是固定的,这类问题的可以用模板设计模式来解决。

定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重新定义该算法的某些特定的步骤。

使用场景

  • 多个子类有公有的方法,并且逻辑基本相同的时候。
  • 重要复杂的算法,可以把核心的算法设计成模板方法,周边的相关细节功能,则有各个子类去实现。
  • 重构的时候,模板方法是一个经常使用的方法,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

简单实现

模板方法实际上就是封装一个固定的流程,就像是执行一套模板一样,第一步该做什么,第二步该做什么都已经在抽象类中定义好了。而子类可以有不同的算法的实现,在框架不被修改的情况下实现某些步骤的算法替换。

以打开计算机为例,来演示一下模板方法。打开计算机的过程,启动电源,计算机检测自身状态没有问题的时候进入操作系统,对用户进行验证之后即可登录计算机。

抽象的电脑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public abstract class AbstractComputer {

protected void powerOn(){
System.out.println("开启电源");
}

protected void checkHardware(){
System.out.println("硬件检查");
}

protected void loadOs(){
System.out.println("载入操作系统");
}

protected void login(){
System.out.println("小白的计算机无验证,直接进入操作系统");
}


public final void startUp(){
System.out.println("----关机start----");
powerOn();
checkHardware();
loadOs();
login();
System.out.println("----关机end----");
}
}

程序员的计算机

1
2
3
4
5
6
public class CoderComputer extends AbstractComputer{
@Override
protected void login() {
System.out.println("程序员只需要进行用户跟密码验证就好了。");
}
}

军用计算机

1
2
3
4
5
6
7
8
9
10
11
12
public class MilitrayComputer extends AbstractComputer{
@Override
protected void checkHardware() {
super.checkHardware();
System.out.println("检查硬件防火墙。");
}

@Override
protected void login() {
System.out.println("进行指纹识别等复杂的用户验证。");
}
}

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {

AbstractComputer comp = new CoderComputer();
comp.startUp();

comp = new MilitrayComputer();
comp.startUp();

}

在startUp中有一些固定的步骤,这四个步骤在计算机开启的过程中是固定不变的。但是不同用户的这几个步骤的实现可能不同,因此子类需要复写响应的方法来进行自定义的处理,这里需要注意的startUp为final方法,这样就保证了逻辑流程不会被子类修改,子类只能够改版某一步骤的具体的实现,这样就保证了这个逻辑流程的稳定性。startUp方法中的这几个算法步骤我们可以称之为一个套路,也称为模板方法。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器