基本介绍
模板模式也被称为“模板方法模式”,该模式是行为型模式的一种,模板模式相对来说比较简单也比较容易理解。
该模式的实现思路是:在一抽象类中定义一个公开的模板方法,该方法规定了某一算法(也可称为功能)的执行流程,其子类可以按照需求重写类中的其它方法,但是整个算法将以模板方法定义的流程进行。
换言之,模板方法规定了一个算法的整体骨架(执行流程),并将一些具体步骤延迟到子类中,从而促使子类可以在不改变算法结构的前提下,就能做到重新定义该算法的一些特定操作。
通常情况下我们会在模板方法所在的父类中定义一个方法,该方法默认不做任何事情,子类可以根据自身情况重写它,此方法被称为“钩子方法”。钩子方法在模板模式中可有可无,不是必须存在的。
模板模式的UML类图
类图讲解
AbstractClass:抽象父类,定义并实现了模板方法,规定好了算法的执行流程。该类中也会存在一些其它抽象方法,用于让子类定制属于自己的特殊操作。
ConcreteClassA、ConcreteClassB:继承AbstractClass抽象类并实现该类中的抽象方法。
Client:客户端测试类。
案例讲解
咖啡制作
流程:挑选咖啡豆 => 研磨 => 冲泡 => 添加配料。
配料:牛奶、糖。
代码实现
咖啡 => 对应AbstractClass
public abstract class Coffee {
/**
* 模板方法,使用final修饰,不让子类重写。 该方法定义了咖啡的制作过程。
*/
public final void make() {
this.select();
this.grind();
this.infusion();
if (this.customerWantCondiments()) {
this.addCondiments();
}
}
// 挑选材料
private void select() {
System.out.println("挑选好优质的咖啡豆!");
}
// 研磨
private void grind() {
System.out.println("将咖啡豆研磨成粉!");
}
// 冲泡
private void infusion() {
System.out.println("冲泡咖啡!");
}
// 添加配料。定义成抽象方法,让不同子类实现添加不同的配料。
public abstract void addCondiments();
/**
* 是否需要添加配料。“钩子方法”
*/
public boolean customerWantCondiments() {
return true;
}
}
不同口味的咖啡 => 对应AbstractClass的子类
/**
* 加奶咖啡
*/
public class WhiteCoffee extends Coffee {
@Override
public void addCondiments() {
System.out.println("添加牛奶!");
}
}
/**
* 加糖咖啡
*/
public class WithSugarCoffee extends Coffee {
@Override
public void addCondiments() {
System.out.println("添加糖!");
}
}
/**
* 纯咖啡
*/
public class PureCoffee extends Coffee {
@Override
public void addCondiments() {
}
// 重写钩子方法
@Override
public boolean customerWantCondiments() {
return false;
}
}
客户端测试类
public class Cilent {
public static void main(String[] args) {
System.out.println("======制作加奶咖啡======");
Coffee whiteCoffee = new WhiteCoffee();
whiteCoffee.make();
System.out.println("======制作加糖咖啡======");
Coffee withSugarCoffee = new WithSugarCoffee();
withSugarCoffee.make();
System.out.println("======制作纯咖啡======");
Coffee pureCoffee = new PureCoffee();
pureCoffee.make();
}
}
执行结果
总结
1、算法(流程)只存在于父类中,这样有利于对算法的修改与维护,只要变更父类就可以使其子类继承相应的修改。
2、模板模式中父类的模板方法和一些已经实现的方法可以直接被子类使用,从而实现代码的最大化复用。
3、模板模式即统一了算法(流程),也提供了很大的灵活性(像上面案例中添加配料一样)。
4、缺点:每一个不同的实现都需要新增一个子类,会导致类的个数增加,使系统变得庞大。
5、注意:父类的模板方法一般都使用final修饰,从而防止子类重写。
6、使用场景:当某一项功能是需要通过执行一系列操作来完成的,并且这一系列的操作基本相同,只有部分操作存在差异时我们就可以考虑使用模板方法。
今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞加关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。