模板方法模式 行为模型的一种 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 模式模型 其实可以理解为一个继承模型,父类一般为抽象类,提供几个固定的模板方法。子类继承父类,子类覆写父类未实现的方法. 在调用的时候直接使用父类的类型来直接调用方法. 这里有两个角色: 抽象模板(Abstract Template)角色 : 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。 定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。 具体模板(Concrete Template)角色 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。 每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。 来的图了,直接找网上的截图了. 模板方法中的方法可以分为两大类: 模板方法 和 基本方法 。 模板方法 一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。 一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。 基本方法 基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。 ● 抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字表示。 ● 具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。 ● 钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。钩子方法的名字建议使用do开始 在上面的例子中,AbstractTemplate是一个抽象类,它带有三个方法。其中abstractMethod()是一个抽象方法,它由抽象类声明为抽象方法,并由子类实现;hookMethod()是一个钩子方法,它由抽象类声明并提供默认实现,并且由子类置换掉。concreteMethod()是一个具体方法,它由抽象类声明并实现。 实例 比如说我们列一天的日常计划: 1、早上起床 跑步 吃早饭 2、中午 吃午饭 -午休 3、晚上 吃晚饭 - 加班 - 健身 - 睡觉 假设我们很自律那么每天都是按照这个计划框架来。一般都是早上才看吃什么,到中午了在看吃什么,到了晚上才知道吃什么。 因此具体的对应 吃早饭、吃午饭、吃晚饭(吃货附体)这几件事具体一点的细节我们是无法确定的。 安静!!! 抽象模板: public abstract class AbstractDailyPlan { // 早上起床 跑步 吃早饭 void morningPlan(){ System.out.println("------ 起床了 ------"); // 跑步 run(); // 吃早饭 doBreakfast(); } // 跑步 void run(){ System.out.println("早期的虫儿被鸟吃"); } void doBreakfast(){ throw new ExceptionInInitializerError("早上吃啥??"); } void noondayPlan(){ System.out.println("------ 午休了 ------"); // 吃午饭 - doLunch(); // 午休 sleepMid(); } abstract void doLunch(); void sleepMid(){ System.out.println("~~huhu~~wujiao~~"); } // 晚上 吃晚饭 - 加班 - 健身 - 睡觉 void nightPlan(){ System.out.println("------ 下班了 ------"); doDinner(); workExtra(); doexercise(); sleep(); } void doDinner(){ System.out.println("减肥,不吃了"); } void workExtra(){ System.out.println("默认不加班"); } abstract void doexercise(); void sleep(){ System.out.println("~洗澡澡~脱光光~睡觉觉~"); } } 具体模板 public class DailyPlanMonday extends AbstractDailyPlan{ @Override void doLunch() { System.out.println("吃盒饭吧"); } @Override void doexercise() { System.out.println("今天练习深蹲"); } @Override void doBreakfast() { System.out.println("~~豆浆~~烧饼~~"); } } 测试类: public class Test { public static void main(String[] args) { AbstractDailyPlan dailyPlan = new DailyPlanMonday(); // 早上的计划 dailyPlan.morningPlan(); // 中午的计划 dailyPlan.noondayPlan(); // 晚上的计划 dailyPlan.nightPlan(); } } 输出结果: ------ 起床了 ------ 早期的虫儿被鸟吃 ~~豆浆~~烧饼~~ ------ 午休了 ------ 吃盒饭吧 ~~huhu~~wujiao~~ ------ 下班了 ------ 减肥,不吃了 默认不加班 今天练习深蹲 ~洗澡澡~脱光光~睡觉觉~ 思考下我们例子中的方法哪些属于钩子方法,具体都是如何做的。 封面图,侵权删。看图点赞、关注的都能中五百万