【设计模式系列】模板方法模式

这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

前言

假设我们需要建造一座房子,需要的步骤有:建地基->砌墙->盖房顶。

我们的需求是需要建水泥房,还要建木头房,那么对应的步骤可能需要处理的逻辑不同,但是执行步骤是固定的,那么固定执行的步骤可以作为方法模板定义。

模板方法定义

模板方法是一种行为设计模式。模板方法设计模式用于创建方法执行模板,并将一些实现步骤推迟到子类。

模板方法定义了方法执行的步骤,它可以提供所有或部分子类通用的默认实现。

模板方法超类

我们来完成最前面的例子,建房子需要做的步骤有:建地基、砌墙和盖房顶。重要的一点是,我们不能改变执行顺序,因为我们不能在建地基之前盖房顶嘛。在这种情况下,我们可以创建一个模板方法,使用不同的方法来构建房子。

现在,盖房子的地基对于所有类型的房子都是一样的,无论是木房子还是水泥房子。我们可以提供基本实现,如果子类想重写这个方法也可以,但是多数情况下它对所有类型的房子都是通用的。

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
java复制代码/**
* @author 小黑说Java
* @ClassName HouseBuildTemplate
* @Description 修建房屋模板
* @date 2021/11/14
**/
public abstract class HouseTemplate {

// 建房子的模板
public final void buildHouse() {
// 1.建地基
buildFoundation();
// 2.砌墙
buildWalls();
// 3.盖房顶
buildRoof();
System.out.println("房子修建完毕。");
}

private void buildFoundation() {
System.out.println("建地基~");
}

protected abstract void buildWalls();

protected abstract void buildRoof() ;
}

为了确保子类不会重写模板方法,应该将buildHouse()其设置为final的。

模板方法实现类

由于我们需要建木头房子和水泥房子,一些方法是需要由子类实现,所以必须将基类设置为抽象类。

木头房

1
2
3
4
5
6
7
8
9
10
11
java复制代码public class WoodHouse extends HouseTemplate {
@Override
protected void buildWalls() {
System.out.println("用木头砌墙");
}

@Override
protected void buildRoof() {
System.out.println("盖木头房顶");
}
}

水泥房

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
java复制代码/**
* @author 小黑说Java
* @ClassName CementHouse
* @Description 水泥房
* @date 2021/11/14
**/
public class CementHouse extends HouseTemplate {
@Override
protected void buildWalls() {
System.out.println("修水泥墙~");
}

@Override
protected void buildRoof() {
System.out.println("盖水泥房顶");
}
}

模板方法客户端

让我们用一个测试程序来测试模板方法模式示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码/**
* @author 小黑说Java
* @ClassName TemplateMethodTest
* @date 2021/11/14
**/
public class TemplateMethodTest {
public static void main(String[] args) {
// 使用模板方法
WoodHouse woodHouse = new WoodHouse();
woodHouse.buildHouse();
System.out.println("-----------------");
CementHouse cementHouse = new CementHouse();
cementHouse.buildHouse();
}
}

注意,客户端正在调用基类的模板方法,根据不同步骤的实现,它使用了来自基类的一些方法和来自子类的一些方法。

运行结果:

模板方法类图

JDK中的模板方法模式

  • java.io.InputStream,java.io.OutputStream,java.io.Reader,java.io.Writer中的非抽象方法。
  • java.util.AbstractList,java.util.AbstractSet,java.util.AbstractMap中的非抽象方法。

模板方法设计模式要点

  1. 模板方法由固定的步骤组成,模板方法应该是final的,对于某些步骤,基类和子类的实现可以是不同的;
  2. 大多数时候,子类调用父类中的方法,但在模板方法模式中,超类模板方法调用子类中的方法;
  3. 基类的默认实现方法称为hooks,他们是为了被子类覆盖,如果你想要一些不覆盖的方法,可以将方法修饰为final。

以上就是模板方法模式的全部内容,如果对你有帮助,点个赞吧!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%