定义
模板方法模式 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。它是一种类行为型模式。
这个模式是用来创建一个算法的模板。什么是模板? 模板就是一个方法。更具体地说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。
特点
- 封装不变的部分,扩展可变的部分。不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
- 父类提取公共部分的代码,避免子类出现重复代码。
- 父类的抽象方法由子类实现,子类执行的结果会影响父类的结果。
- 由于继承关系自身的缺点,当父类添加新抽象方法时,所有子类都必须实现新增的抽象方法。
UML结构
f1x939.pngCode结构
// 抽象类
abstract class AbstractClass {
// 模板方法,定义了一个算法的步骤,避免子类干扰步骤,使用final进行方法修饰
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
concreteOperation();
hook();
}
// 抽象类方法,必须由子类进行具体实现
abstract void primitiveOperation1();
// 抽象类方法,必须由子类进行具体实现
abstract void primitiveOperation2();
// 具有共性的由父类直接实现,同时使用final修饰避免子类覆盖它
public final void concreteOperation() {
// 这里是实现
}
// 当子类必须提供算法中某个方法或步骤的实现,并且这个实现为可选调用时就可以使用钩子方法
void hook() {}
}
// 具体子类
class ConcreteClass extends AbstractClass {
public void primitiveOperation1() {
System.out.println("抽象方法1的实现被调用...");
}
public void primitiveOperation2() {
System.out.println("抽象方法2的实现被调用...");
}
}
public static void main(String[] args) {
AbstractClass tm = new ConcreteClass();
tm.templateMethod();
}
场景示例
/**
* 咖啡因饮料模板类
*/
public abstract class CaffeineBeverages {
/*
* 模板方法
* 封装了制作咖啡因饮料过程的算法框架
*/
public final void driveTemplate(){
// 1.将水煮沸
boilWater();
// 2. 炮制饮料
blew();
// 3. 倒入杯中
pourInCup();
// 钩子函数 判定(例如茶不想加入调味料)
if(isRight()){
// 4. 进入调味料
addCondiments();
}
}
/*
* 基本方法,将水煮沸
*/
private void boilWater() {
System.out.println("将水煮沸");
}
/*
* 基本方法,倒入杯中
*/
private void pourInCup() {
System.out.println("倒入杯中");
}
/*
* 抽象方法 加入调味料(可选)
* 需由子类实现
*/
public abstract void addCondiments();
/*
* 抽象方法 炮制饮料(可选)
* 需由子类实现
*/
public abstract void blew();
// 钩子函数 判断用户是否要执行某些 “可选” 功能
public boolean isRight(){
return true;
}
}
/**
* 制备茶的具体实现类
*/
public class Tea extends CaffeineBeverages {
// 添加调料
@Override
public void addCondiments() {
System.out.println("加入柠檬");
}
// 冲泡茶
@Override
public void blew() {
System.out.println("用80度的热水浸泡茶叶5分钟");
}
// 重写钩子函数 改变其值
@Override
public boolean isRight(){
return false;
}
}
网友评论