介绍

模板模式(Template )是一种设计模式,它定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。这样,子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
在 Java 中,模板模式通常使用抽象类和抽象方法来实现。抽象类中定义了一系列抽象方法,这些方法将在子类中实现。抽象类还可以定义一些非抽象方法,这些方法可以直接在抽象类中实现,也可以留给子类实现。抽象类中定义的方法组成了算法的骨架

结构

模式中的角色:

  • 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
  • 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法

通用代码如下

抽象模板类

1
2
3
4
5
6
7
8
9
10
11
public abstract class AbstractClass {
// 基本方法
protected abstract void doSomething();
// 基本方法
protected abstract void doAnything();
// 模版方法,完成相关逻辑
public void templateMethod(){
this.doAnything();
this.doAnything();
}
}

具体模板类

1
2
3
4
5
6
7
8
9
10
11
12
public class ConcreteClass1 extends AbstractClass{
// 实现基本方法
@Override
protected void doSomething() {
System.out.println("ConcreteClass1 -- doSomething");
}

@Override
protected void doAnything() {
System.out.println("ConcreteClass1 -- doAnything");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public class ConcreteClass2 extends AbstractClass{
// 实现基本方法
@Override
protected void doSomething() {
System.out.println("ConcreteClass2 -- doSomething");
}

@Override
protected void doAnything() {
System.out.println("ConcreteClass2 -- doAnything");
}
}

场景类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Client {
public static void main(String[] args) {
AbstractClass abstractClass1 = new ConcreteClass1();
AbstractClass abstractClass2 = new ConcreteClass2();

abstractClass1.templateMethod();
abstractClass2.templateMethod();
}
}
/*
ConcreteClass1 -- doSomething
ConcreteClass1 -- doAnything
ConcreteClass2 -- doSomething
ConcreteClass2 -- doAnything
*/

简单例子

父类定义了制作炸鸡的方法,而制作一只炸鸡需要养殖->屠宰->油炸,这三个步骤分别定义成一个方法等待子类来重写,因为不同的厂家制作炸鸡在每一步都是有一定的差异的

抽象模版类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.base.learn;

public abstract class AbstractFriedChicken {

/**
* 定义一套制作炸鸡的步骤
*/
protected final void makeFriedChicken() {
breed();
slaughter();
fried();
}

// 养殖方法,等待之类实现
protected abstract void breed();

// 屠宰方法,等待子类实现
protected abstract void slaughter();

// 油炸方法,等待之类实现
protected abstract void fried();

}

子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.base.learn;

public class McDonald extends AbstractFriedChicken{

@Override
protected void breed() {
System.out.println("麦当劳养殖场,每天喂食4次");
}

@Override
protected void slaughter() {
System.out.println("麦当劳人工屠宰");
}

@Override
protected void fried() {
System.out.println("麦当劳油炸3遍");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.base.learn;

public class KFC extends AbstractFriedChicken{
@Override
protected void breed() {
System.out.println("肯德基养殖场,每天喂食2次");
}

@Override
protected void slaughter() {
System.out.println("肯德基机器屠宰");
}

@Override
protected void fried() {
System.out.println("肯德基油炸2遍");
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.base.learn;

public class Test {
public static void main(String[] args) {
AbstractFriedChicken mcDonald = new McDonald();
AbstractFriedChicken kfc = new KFC();

mcDonald.makeFriedChicken();
System.out.println("-----------");
kfc.makeFriedChicken();

}
}

/*
麦当劳养殖场,每天喂食4次
麦当劳人工屠宰
麦当劳油炸3遍
-----------
肯德基养殖场,每天喂食2次
肯德基机器屠宰
肯德基油炸2遍
*/

参考