在我们的日常生活中,模板方法是应用的很广的,我们身边有很多模板方法的身影,举个很高大上的例子就是我们的奥运会的开幕仪式:奥委会对于不同国家举办奥运会开幕式提供的步骤都是一样的:
1.升国旗,奏国歌
2.奥委会人发言
3.文艺汇演
4.奥运运动员入场仪式
5.点燃火炬
但是,对于不同的国家,他们的内容肯定是不一样的,这就是一种模板方法。那么,我们在java的实现中,应该是怎么进行表现呢?
这里再用一个例子来演示,我们的饮料机,一个饮料机可以制作咖啡和茶:
那么我们先定义一个制作饮料的抽象基类:
package com.imooc.pattern.template; /* * 抽象基类,为所有子类提供一个算法框架 * * 饮料 */ public abstract class RefreshBeverage { /* * 制备饮料的模板方法 * 封装了所有子类共同遵循的算法框架 */ public final void prepareBeverageTemplate(){ //步骤1 将水煮沸 boilWater(); //步骤2 泡制饮料 brew(); //步骤3 将饮料倒入杯中 pourInCup(); if(isCustomerWantsCondiments()){ //步骤4 加入调味料 addCondiments(); } } /* * Hook, 钩子函数,提供一个默认或空的实现 * 具体的子类可以自行决定是否挂钩以及如何挂钩 * 询问用户是否加入调料 */ protected boolean isCustomerWantsCondiments() { return true; } /* * 基本方法,将水煮沸 */ private void boilWater() { System.out.println("将水煮沸"); } /* * 基本方法,将饮料倒入杯中 */ private void pourInCup() { System.out.println("将饮料倒入杯中"); } /* * 抽象的基本方法,泡制饮料 */ protected abstract void brew(); /* * 抽象的基本方法, 加入调味料 */ protected abstract void addCondiments(); }
是的,制作茶和咖啡的步骤都是一样的,唯一不同的就是炮制和加调味料的实现不一样,所以定义一个模板方法为final,再将其两个不同的方法设置为protected属性,这样方法就只能在它的子类中进行访问和修改了。就能做到不同的饮料不同的制作
所以,制作茶:
package com.imooc.pattern.template; /* * 抽象基类,为所有子类提供一个算法框架 * * 提神饮料 */ public abstract class RefreshBeverage { /* * 制备饮料的模板方法 * 封装了所有子类共同遵循的算法框架 */ public final void prepareBeverageTemplate(){ //步骤1 将水煮沸 boilWater(); //步骤2 泡制饮料 brew(); //步骤3 将饮料倒入杯中 pourInCup(); if(isCustomerWantsCondiments()){ //步骤4 加入调味料 addCondiments(); } } /* * Hook, 钩子函数,提供一个默认或空的实现 * 具体的子类可以自行决定是否挂钩以及如何挂钩 * 询问用户是否加入调料 */ protected boolean isCustomerWantsCondiments() { return true; } /* * 基本方法,将水煮沸 */ private void boilWater() { System.out.println("将水煮沸"); } /* * 基本方法,将饮料倒入杯中 */ private void pourInCup() { System.out.println("将饮料倒入杯中"); } /* * 抽象的基本方法,泡制饮料 */ protected abstract void brew(); /* * 抽象的基本方法, 加入调味料 */ protected abstract void addCondiments(); }
制作咖啡:
package com.imooc.pattern.template; /* * 具体子类,提供了咖啡制备的具体实现 */ public class Coffee extends RefreshBeverage { @Override protected void brew() { System.out.println("用沸水冲泡咖啡"); } @Override protected void addCondiments() { System.out.println("加入糖和牛奶"); } }
测试:
package com.imooc.pattern.template; public class RefreshBeverageTest { public static void main(String[] args) { System.out.println("制备咖啡..."); RefreshBeverage b1 = new Coffee(); b1.prepareBeverageTemplate(); System.out.println("咖啡好了!"); System.out.println("\n******************************************"); System.out.println("制备茶..."); RefreshBeverage b2 = new Tea(); b2.prepareBeverageTemplate(); System.out.println("茶好了!"); } }
所以,模板方法最重要的就是定义一个抽象基类,模板方法定位finnal,具体子类实现抽象基类的抽象方法,实现个性化的类的操作,钩子方法的设定是让个性化更加详细。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-07 16:04:09