@BertLee
2017-08-17T12:44:12.000000Z
字数 1689
阅读 1383
模板方法模式通过把不变的行为搬移到父类(抽象类),去除了子类中的重复代码;对于不同的子类有不同实现的行为,在父类中声明一些抽象方法来迫使子类实现剩余的逻辑,提高程序的扩展性。
模板方法有如下几种角色:
抽象模板角色:抽象类,该类包含以下几类方法:
1. 模板方法:final类型的具体方法,给出了实现业务操作的顶级逻辑,内部调用了由子类实现的抽象方法。
2. 抽象方法:实现顶级逻辑的基本操作,由子类实现。
3. 钩子方法:具体方法,方法体为空,可被子类置换。
4. 具体方法:private类型的具体方法,作为实现顶级逻辑的一部分基本操作。
具体模板角色:具体类
模板方法模式的结构如下图:
套路:
1. 梳理原类中方法的业务逻辑,抽象出顶级逻辑,形成抽象模板类,模板方法,抽象方法
2. 根据职责划分,创建相关子类,形成具体模板类,形成具体操作方法
/*** 抽象模板角色-打印机*/public abstract class Printer {//模板方法public final double getAmount(int num){String printType = getPrinterType();double paperPrice = getPaperPrice(printType);return num * paperPrice;}//钩子方法public String getPrinterName(){return null;}//抽象方法protected abstract String getPrinterType();//抽象方法protected abstract double getPaperPrice(String printerType);//具体方法private void print(){//打印相关业务}}
/*** 具体模板角色-石墨打印机*/public class GraphitePrinter extends Printer{@Overrideprotected String getPrinterType() {return "石墨打印";}@Overrideprotected double getPaperPrice(String printerType) {if("石墨打印".equals(printerType)){return 1;}else{throw new RuntimeException("没有" + printerType + "这种类型");}}}
/*** 具体模板角色-激光打印机*/public class LaserPrinter extends Printer{@Overrideprotected String getPrinterType() {return "激光打印";}@Overrideprotected double getPaperPrice(String printerType) {if("激光打印".equals(printerType)){return 2;}else{throw new RuntimeException("没有" + printerType + "这种类型");}}}
/*** 测试模板方法模式.*/public class TemplateMethodTest {@Testpublic void testTemplateMethod(){//1.激光打印3张纸new LaserPrinter().getAmount(3);//2.石墨打印3张纸new GraphitePrinter().getAmount(3);}}
吹牛:
1.模板方法模式展现继承复用的可用之地,以往都是采用委派关系来代继承关系
2. 当方法包含了太多的代码时,不妨试着抽取几个类,几个方法,利用模板方法模式重构一下
撰写本文考了不少博文,在此一并谢过。
《JAVA与模式》之模板方法模式转载时,请注明出处,这是人格的一种体现。
https://www.zybuluo.com/BertLee/note/853031- 能力有限,如有纰漏,请在评论区指出,老朽虽一把年纪,必当感激涕零,泪如雨下。若有满嘴喷粪撕逼者,一律拉黑、举报。