• 行为型之模板方法模式


    序言

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

    • 抽象模板角色:抽象类,该类包含以下几类方法:
        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. 当方法包含了太多的代码时,不妨试着抽取几个类,几个方法,利用模板方法模式重构一下

    后记

  • 相关阅读:
    HyperV创建NAT网络
    Win10
    ConEmu
    ffmpeg的centos、msys2、msvc编译
    7z压缩gopath的src的批处理
    VS2015自带v120的Platform Toolset
    Putty配置
    第一章:HTML5的基础
    java的错题整理
    第十四章:类的带参方法
  • 原文地址:https://www.cnblogs.com/codebug/p/7384278.html
Copyright © 2020-2023  润新知