版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/love905661433/article/details/84430846
概述
- 定义 : 定义了一个算法的骨架, 并允许子类为一个或多个步骤提供实现
- 模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法的某些步骤
- 类型 : 行为型
适用场景
- 一次性实现一个算法的不变的部分, 并将可变的行为留给子类来实现
- 各子类中公共的行为被提取出来并集中到一个公共的父类中, 从而避免代码重复
优点
- 提供复用性
- 提高扩展性
- 符合开闭原则
缺点
- 类数目增加
- 增加了系统实现的复杂度
- 继承关系自身缺点, 如果父类添加新的抽象方法, 那么所有子类都要修改
扩展
- 钩子方法
模式角色
-
AbstractClass(抽象类) :
- 定义抽象的原语操作(primitive operation),具体的子类将重定义它们以实现一个算法的各步骤。
- 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义
在AbstractClass或其他对象中的操作。
-
ConcreteClass(具体类) : 实现原语操作以完成算法中与特定子类相关的步骤
代码实现
场景
将一件东西放入冰箱, 需要如下步骤:
- 给冰箱通电(如果需要)
- 打开冰箱(公共方法)
- 放入东西 -子类重写选择放入什么东西
- 关闭冰箱
代码
AbstractClass :
/**
* 抽象类
*
* @author 七夜雪
* @create 2018-11-24 11:02
*/
public abstract class AbstractClass {
public void excute(){
if (isNeedPrepare()) {
prepare();
}
openFridge();
put();
closeFridge();
}
public void prepare(){
System.out.println("给冰箱通电...");
}
// 钩子方法, 子类可以通过重写这个方法控制prepare方法是否执行
public boolean isNeedPrepare(){
return false;
}
public void openFridge(){
System.out.println("打开冰箱...");
}
public abstract void put();
public void closeFridge(){
System.out.println("关闭冰箱...");
}
}
ConcreteClass1, 重写了钩子方法 :
/**
* 子类1 : 将大象放入冰箱
*
* @author 七夜雪
* @create 2018-11-24 11:08
*/
public class ConcreteClass1 extends AbstractClass {
@Override
public void put() {
System.out.println("将大象放入冰箱...");
}
@Override
public boolean isNeedPrepare() {
return true;
}
}
ConcreteClass2 :
/**
* 子类2 : 将老虎放入冰箱
*
* @author 七夜雪
* @create 2018-11-24 11:08
*/
public class ConcreteClass2 extends AbstractClass {
@Override
public void put() {
System.out.println("将老虎放入冰箱...");
}
}
测试代码 :
/**
* @author 七夜雪
* @create 2018-11-24 11:12
*/
public class Client {
public static void main(String[] args) {
AbstractClass cls1 = new ConcreteClass1();
AbstractClass cls2 = new ConcreteClass2();
cls1.excute();
cls2.excute();
}
}
测试结果:
给冰箱通电...
打开冰箱...
将大象放入冰箱...
关闭冰箱...
打开冰箱...
将老虎放入冰箱...
关闭冰箱...
本文参考:
慕课网<java设计模式精讲 Debug 方式+内存分析>课程
四人帮<设计模式>