0%

设计模式之Template Method模式

介绍

  • 意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
  • 如何解决:在父类中定义处理流程的框架,在子类中实现具体处理的模式.
  • 应用实例:
  1. 盖房子的过程都是一样,地基,走线,房梁,装修等. 不同是我们是盖什么房子,用什么材料盖.
  2. spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。
  • 优点:
    • 封装不变部分,扩展可变部分.
    • 提供公共代码,便于维护
    • 行为由父类控制,子类实现.
  • 缺点:
    • 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
  • 使用场景:
  1. 有多个子类共有的方法,且逻辑相同
  2. 重要的、复杂的方法,可以考虑作为模板方法。
  • 注意事项:为防止恶意操作,一般模板方法都加上 final 关键词。

实现

我们将创建一个定义操作的 Game 抽象类,其中,模板方法设置为 final,这样它就不会被重写。Cricket 和 Football 是扩展了 Game 的实体类,它们重写了抽象类的方法。
TemplatePatternDemo,我们的演示类使用 Game 来演示模板模式的用法。
示例的类图

创建一个抽象类,它的模板方法被设置为 final。
Game.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.edu.tju.GOF.Template;

public abstract class Game {
abstract void initialize();

abstract void startPlay();

abstract void endPlay();

// 模板
public final void play() {

// 初始化游戏
initialize();

// 开始游戏
startPlay();

// 结束游戏
endPlay();
}
}

创建扩展上述类的实体类
Cricket.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Cricket extends Game {

@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}

@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}

@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}

Football.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Football extends Game {

@Override
void endPlay() {
System.out.println("Football Game Finished!");
}

@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}

@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}

总结

因此说模板非常容易理解,使用起来也很简单,但是在工程中我们往往将模板与其他模式结合起来,因此我们要认清模板的本质,将具有相同操作的多种事物抽象出这些相同的操作,然后将这些操作有机的整合起来变成模板类,另外也要注意在模板方法的定义final表示此方法不能被继承和重写,这无疑是重要的,规定和法则不能被其他人所改变。

类的层次与抽象类

类的层次

  • 站在子类的角度进行思考
    • 在子类中可以使用父类中定义的方法
    • 可以通过在子类中增加方法以实现新的功能
    • 在子类中重写父类的方法可以改变程序的行为
  • 站在父类的角度进行思考
    • 期待子类去实现抽象方法
    • 要求子类去实现抽象方法
      也就是说,子类具有实现在父类中所声明的抽象方法的责任,因此,这种责任被称为”子类责任”(subclass responsibility)

在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

java final关键字

  • 修饰类
    当用final去修饰一个类的时候,表示这个类不能被继承。
    • a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为final。
    • b. final类中的成员方法都会被隐式的指定为final方法。

说明:
在自己设计一个类的时候,要想好这个类将来是否会被继承,如果可以被继承,则该类不能使用fianl修饰,在这里呢,一般来说工具类我们往往都会设计成为一个fianl类。在JDK中,被设计为final类的有String、System等。

  • 修饰方法
    被final修饰的方法不能被重写。

    • a. 一个类的private方法会隐式的被指定为final方法。
    • b. 如果父类中有final修饰的方法,那么子类不能去重写。
  • 修饰变量
    对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

传送🚪

Thank you for your support