zoukankan      html  css  js  c++  java
  • 大话设计模式:模板方法模式

    什么是模板方法?即让工作或流程顺序按照写好的模板进行下去,同时还可以自定义流程,以及简化流程。

    举例:冲泡茶和咖啡均分四步进行:

    1. 把水煮沸
    2. 冲泡咖啡(茶)
    3. 把咖啡(茶)倒入杯子
    4. 加糖(柠檬)

    一般写法

    咖啡类

    public class Coffee {
    
        public void prepare() {
            /**
             * 制作咖啡:
             * 1。 把水煮沸
             * 2。 用水冲泡
             * 3。 把咖啡倒进杯子
             * 4。 加糖
             */
            boilWater();
            brewCoffee();
            pourInCup();
            addSuger();
        }
    
        public void boilWater() {
            System.out.println("把水煮沸");
        }
    
        public void brewCoffee() {
            System.out.println("用水冲泡咖啡");
        }
    
        public void pourInCup() {
            System.out.println("把咖啡倒进杯子");
        }
    
        public void addSuger() {
            System.out.println("加糖");
        }
    
    }
    

    茶类

    public class Tea {
    
        public void prepare() {
            /**
             * 制作茶:
             * 1。 把水煮沸
             * 2。 用水冲泡
             * 3。 把茶倒进杯子
             * 4。 加柠檬
             */
            boilWater();
            pourInCup();
            pourInCup();
            addLemon();
        }
    
        public void boilWater() {
            System.out.println("把水煮沸");
        }
    
        public void brewTea() {
            System.out.println("用水冲泡茶");
        }
    
        public void pourInCup() {
            System.out.println("把茶倒进杯子");
        }
    
        public void addLemon() {
            System.out.println("加柠檬");
        }
    
    }
    

    测试类

    public class Test01 {
    
        /**
         * 这种实现方式有很多重复的代码
         */
        public static void main(String[] args) {
            Coffee coffee = new Coffee();
            Tea tea = new Tea();
            coffee.prepare();
            System.out.println("---------------");
            tea.prepare();
        }
    
    }
    

    模板方法

    定义抽象的模板方法,把公共方法抽离出来,其它交给子类去实现

    public abstract class DrinksTemplate {
    
        /**
         * 设定为final,不让子类去覆盖或篡改流程
         */
        final public void prepare() {
            boilWater();
            brew();
            pourInCup();
            add();
        }
    
        public void boilWater() {
            System.out.println("把水煮沸");
        }
    
        /**
         * 交给子类实现
         */
        public abstract void brew();
    
        public void pourInCup() {
            System.out.println("把饮料倒进杯子");
        }
    
        public abstract void add();
    
    }
    

    咖啡类

    public class Coffee extends DrinksTemplate {
    
        @Override
        public void brew() {
            System.out.println("用沸水冲泡咖啡");
        }
    
        @Override
        public void add() {
            System.out.println("加糖");
        }
    }
    

    茶类

    public class Tea extends DrinksTemplate {
    
        @Override
        public void brew() {
            System.out.println("用沸水冲泡茶");
        }
    
        @Override
        public void add() {
            System.out.println("加柠檬");
        }
    }
    

    测试类

    public class Test01 {
    
        public static void main(String[] args) {
            Coffee coffee = new Coffee();
            Tea tea = new Tea();
            coffee.prepare();
            System.out.println("-----------");
            tea.prepare();
        }
    
    }
    

    使用钩子函数

    钩子函数是在抽象模板方法中定义的,它的作用就是控制流程中的某个步骤是否执行、简化流程,子类可以选择覆盖。比如,在准备给用户冲泡咖啡或茶之前询问用户是否需要加糖或者柠檬,不需要就不进行加糖或柠檬这一步骤了。

    抽象模板方法

    public abstract class DrinksTemplate {
    
        /**
         * 设定为final,不让子类去覆盖或篡改流程
         */
        final public void prepare() {
            boilWater();
            brew();
            pourInCup();
            if (ifAdd()) {
                add();
            }
        }
    
        public void boilWater() {
            System.out.println("把水煮沸");
        }
    
        /**
         * 交给子类实现
         */
        public abstract void brew();
    
        public void pourInCup() {
            System.out.println("把饮料倒进杯子");
        }
    
        public abstract void add();
    
        /**
         * 钩子函数
         */
        public Boolean ifAdd() {
            return true;
        }
    
    }
    

    只让茶类去覆盖钩子函数

    @Data
    public class Tea extends DrinksTemplate {
    
        private Boolean ifAdd;
    
        @Override
        public void brew() {
            System.out.println("用沸水冲泡茶");
        }
    
        @Override
        public void add() {
            System.out.println("加柠檬");
        }
    
        @Override
        public Boolean ifAdd() {
            return ifAdd;
        }
    }
    

    测试类

    @SuppressWarnings("Duplicates")
    public class Test01 {
    
        public static void main(String[] args) {
            Coffee coffee = new Coffee();
            Tea tea = new Tea();
            // 启用钩子函数
            tea.setIfAdd(false);
            coffee.prepare();
            System.out.println("==========");
            tea.prepare();
        }
    
    }
    

    测试结果

    把水煮沸
    用沸水冲泡咖啡
    把饮料倒进杯子
    加糖
    ==========
    把水煮沸
    用沸水冲泡茶
    把饮料倒进杯子
    
  • 相关阅读:
    Camunda工作流——第三章 网关
    Camunda工作流——第二章 任务
    Camunda工作流——第一章 参与者
    需求库规划库储备库四库更新区域类型到meta_localinfo表
    备份需求库规划库储备库四库数据到temp模式里
    php 处理高精度计算函数
    php 使用file_put_content将 数据 push 到csv文件中
    忘记rabbitmq账号密码?创建rabbitmq新用户
    docker+nginx+consul+swoft 实现动态负载均衡
    docker 基础操作
  • 原文地址:https://www.cnblogs.com/zhangjianbing/p/13654891.html
Copyright © 2011-2022 走看看