模板模式
2017-08-17 17:27 grows 阅读(245) 评论(0) 编辑 收藏 举报- 模板模式
模板模式:即提供一个统一的模板算法(执行每个方法的顺序,以及那一部分需要执行,那一部分不需要执行),而其中需要频繁变化的部分设计为抽象的,而固定不变的部分设计具体的方法,如果需要改变模板中的某个流程,则使用钩子方法。
其是基于继承的代码复用技术
- 角色
1) 抽象类:用于设计具体的模板(包括四种方法)
- 具体方法:写业务逻辑中不变的部分
- 抽象方法:写需要根据逻辑方法变化的部分
- 钩子方法:想要改变模板方法中方法执行流程的部分,
- 模板方法:根据业务逻辑具体的执行流程,一般设计为final 类型以防止被重写
2) 具体类:实现抽象类中的某个抽象方法,需要变化的,或者重写具体方法,或者重写控制算法流程的钩子方法
- 特别分析:
钩子方法通常设计为具体的没有任何实现的类或者是返回true的方法,用来控制模板方法中的流程
- 代码实现
例如:我们种花的时候一般分为:(买盆 or 不买盆)——选择花——装土——浇水
分析:
1) 如果要是直接种到土地里面买盆就不是必须的,如果种到花盆中则需要买,所以这里有个判断的过程(这时候我们需要把用一个钩子方法,用子类控制是否买盆,或者采用默认的形式),
2) 选择哪种花是不固定的,需要具体的子类来实现买什么样子的花
3) 装土是固定的
4) 浇水也是必须的
抽象方法:种花
package templatemodel; public abstract class PlantFlowers { /** * 钩子方法,用来控制模板方法中的流程 * @return */ public boolean isBuyBasin(){ return true; } /** * 买盆,固定方法不会发生变化,根据需要判断是否调用 */ public void buyBasin(){ System.out.println("买盆。。。"); } /** * 选择花的类型,不固定,让子类去实现具体选哪种花 */ public abstract void choseFlower(); /** * 装土,固定方法不会发生变化,但是也可以让子类重写 */ public void useSoil() { System.out.println("装土。。。。"); } /** * 浇水,固定方法不会发生变化,但是也可以让子类重写 */ public void useWater() { System.out.println("浇水。。。。"); } /** * 模板方法,用于具体的流程 */ public void proccess(){ if(this.isBuyBasin()){ buyBasin();//买盆 } choseFlower();//选花 useSoil();//装土 useWater();//浇水 } }
具体实现类:选择玫瑰
package templatemodel; /** * 选择玫瑰花,采用默认流程即在花盆中种花 * @author Administrator * */ public class ChoseRose extends PlantFlowers { @Override public void choseFlower() { // TODO Auto-generated method stub System.out.println("选择玫瑰花。。"); } }
具体实现类:选择牡丹
package templatemodel; /** * 选择牡丹花,改变钩子方法,即直接在土地上种花 * @author Administrator * */ public class ChosePeony extends PlantFlowers { @Override public void choseFlower() { // TODO Auto-generated method stub System.out.println("选择牡丹花。。"); } @Override public boolean isBuyBasin(){ return false; } }
测试类:
package templatemodel; public class TestTemplate { public static void main(String[] args) { // TODO Auto-generated method stub //种玫瑰花 PlantFlowers plantRose=new ChoseRose(); plantRose.proccess(); System.out.println(); //种牡丹花 PlantFlowers plantPeony=new ChosePeony(); plantPeony.proccess(); } }
结果:
买盆。。。
选择玫瑰花。。
装土。。。。
浇水。。。。
选择牡丹花。。
装土。。。。
浇水。。。。
- 优点
1) 形成一个固定的算法流程具体细节可以由子类去实现,可以是整体保持不变
2) 代码复用,不用去写很多的重复流程,尤其是对于流程固定的场景
- 缺点(感觉优点牵强)
1)不同的实现需要不同子类,如果由大量的实现会导致子类很多
- 场景
1) 大致流程固定,具体的实现想要根据具体的场景在去实现
2) 需要分割复杂的算法,分离出固定的部分和变化的部分,把变化的设计为抽象,具体是由子类去实现,
3) 通过子类来决定是否去改变父类中的流程