行为型之模板方法模式

序言

  模板方法模式通过把不变的行为搬移到父类(抽象类),去除了子类中的重复代码;对于不同的子类有不同实现的行为,在父类中声明一些抽象方法来迫使子类实现剩余的逻辑,提高程序的扩展性。
  模板方法有如下几种角色:

  • 抽象模板角色:抽象类,该类包含以下几类方法:
      1. 模板方法:final类型的具体方法,给出了实现业务操作的顶级逻辑,内部调用了由子类实现的抽象方法。
      2. 抽象方法:实现顶级逻辑的基本操作,由子类实现。
      3. 钩子方法:具体方法,方法体为空,可被子类置换。
      4. 具体方法:private类型的具体方法,作为实现顶级逻辑的一部分基本操作。

  • 具体模板角色:具体类

模板方法模式

  模板方法模式的结构如下图:

![](http://images2017.cnblogs.com/blog/946528/201708/946528-20170817203845615-2128403161.png)

套路:

  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{

    @Override
    protected String getPrinterType() {
        return "石墨打印";
    }

    @Override
    protected double getPaperPrice(String printerType) {

        if("石墨打印".equals(printerType)){
            return 1;

        }else{
            throw new RuntimeException("没有" + printerType + "这种类型");
        }
    }
}
/**
 * 具体模板角色-激光打印机
 */
public class LaserPrinter extends Printer{

    @Override
    protected String getPrinterType() {
        return "激光打印";
    }

    @Override
    protected double getPaperPrice(String printerType) {

        if("激光打印".equals(printerType)){
            return 2;
        }else{
            throw new RuntimeException("没有" + printerType + "这种类型");
        }
    }
}
/**
 * 测试模板方法模式.
 */
public class TemplateMethodTest {
    @Test
    public void testTemplateMethod(){

        //1.激光打印3张纸
        new LaserPrinter().getAmount(3);
        //2.石墨打印3张纸
        new GraphitePrinter().getAmount(3);
    }
}

吹牛:

  1. 模板方法模式展现继承复用的可用之地,以往都是采用委派关系来代继承关系
  2. 当方法包含了太多的代码时,不妨试着抽取几个类,几个方法,利用模板方法模式重构一下

后记

posted @ 2017-08-17 20:39  吃不了兜着走  阅读(145)  评论(0编辑  收藏  举报