行为型:模板方法模式
目录
1、核心思想
2、实现方式
2.1 模式结构
2.2 实现案例
3、优缺点分析
4、适用场景
1、核心思想
目的:父类控制流程,复用公共逻辑,子类灵活扩展,只实现特定步骤。
概念:将总结出来的规律沉淀为一种既定格式,并固化于模板中以供子类继承,对未确立下来的步骤方法进行抽象化,使其得以延续、多态化,最终架构起一个平台,使系统实现在不改变预设规则的前提下,对每个分步骤进行个性化定义。
举例:
1> 烹饪食谱:食谱提供固定步骤(洗菜→切菜→烹饪→装盘),但“烹饪”的具体方式(炒、煮)由子类决定
2> 软件安装向导:安装流程固定(同意协议→选择路径→安装→完成),但不同软件的安装细节可能不同。
2、实现方式
2.1 模式结构
两种核心角色:
- AbstractClass(抽象基类):定义出原始操作步骤的抽象方法以供子类实现,并作为在模板方法中被调用的一个步骤。此外还实现了不可重写的模板方法,其可将所有原始操作组织起来成为一个框架或者平台。
- ConcreteClassA、ConcreteClassB(实现类A、实现类B):继承自抽象基类并且对所有的原始操作进行分步实现,可以有多种实现以呈现每个步骤的多样性。
2.2 实现案例
饮料制作(咖啡和茶的制作流程相似,但部分步骤不同):
// 抽象类(定义模板方法)
abstract class Beverage {// 模板方法(final防止子类覆盖算法结构)public final void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) { // 钩子方法控制是否添加调料addCondiments();}}// 具体方法(公共步骤)private void boilWater() {System.out.println("煮沸水");}private void pourInCup() {System.out.println("倒入杯子");}// 抽象方法(子类必须实现)protected abstract void brew();protected abstract void addCondiments();// 钩子方法(可选扩展,默认返回true)protected boolean customerWantsCondiments() {return true;}
}// 具体子类:咖啡
class Coffee extends Beverage {@Overrideprotected void brew() {System.out.println("冲泡咖啡粉");}@Overrideprotected void addCondiments() {System.out.println("加糖和牛奶");}// 覆盖钩子方法:用户可以选择不加调料@Overrideprotected boolean customerWantsCondiments() {return false; // 假设用户不要调料}
}// 具体子类:茶
class Tea extends Beverage {@Overrideprotected void brew() {System.out.println("浸泡茶叶");}@Overrideprotected void addCondiments() {System.out.println("加柠檬");}
}// 客户端调用
public class Client {public static void main(String[] args) {Beverage coffee = new Coffee();coffee.prepareRecipe(); // 输出:煮沸水 → 冲泡咖啡粉 → 倒入杯子(不加调料)Beverage tea = new Tea();tea.prepareRecipe();// 输出:煮沸水 → 浸泡茶叶 → 倒入杯子 → 加柠檬}
}
关键点:
-
模板方法:通常是
final
方法,确保算法步骤不可被修改。 -
基本方法类型:
-
抽象方法:子类必须实现(如
brew()
)。 -
具体方法:父类已实现(如
boilWater()
)。 -
钩子方法(Hook Method):提供默认实现,子类可选择覆盖(如
customerWantsCondiments()
)。
-
3、优缺点分析
优点 | 缺点 |
---|---|
提高代码复用性(抽取公共逻辑) | 可能导致类爆炸(每变种需一个子类) |
父类控制流程,子类专注细节 | 继承强耦合,违反组合优于继承原则 |
提供扩展点(钩子方法) | 过度使用可能使代码结构复杂化 |
4、适用场景
-
框架设计
-
定义通用流程,如Spring的
JdbcTemplate
(封装连接、执行SQL、关闭连接等步骤)。
-
-
算法复用
-
如数据解析(读取→解析→处理→输出)、游戏循环(初始化→更新→渲染)。
-
-
标准化流程
-
如测试用例(setup→执行→teardown)、审批流程(提交→审核→归档)。
-
-
扩展第三方库
-
重写库中的部分方法,而不影响整体流程。
-