• Java设计模式——模板方法模式


    转载自:https://www.cnblogs.com/zplogo/p/6428593.html

    用抽象基类定义算法框架 RefreshBeverage

    package com.pattern.template;
    
    /**
     * 抽象基类,为其他子类提供一个算法框架 提神饮料
     * 
     *
     */
    public abstract class RefreshBeverage {
    
        /*
         * 制备饮料的模板方法 封装了所有子类所遵循的算法框架
         */
        public final void prepareBeverageTemplate() {
            // 步骤一 将水煮沸
            boilWater();
            // 步骤二 泡制饮料
            brew();
            // 步骤三 将饮料倒入杯中
            pourInCup();
            if (isCustomerWantsCondiments()) {
                // 步骤四 加入调味料
                addCondiments();
            }
        }
    
        /*
         * Hook 钩子函数,提供一个空的或者默认的实现 子类重写该方法,可以自行决定是否挂钩以及如何挂钩
         */
        protected boolean isCustomerWantsCondiments() {
            return true;
        }
    
        // 因为将水煮沸和把饮料倒入杯中对所有子类是共同的行为,所以没必要向子类过多开放,所以方法定义为private,这样我们在进行子类编码时可以减少复杂度。
        // 这样不需要关注细枝末节,我们只需要关注我们特定业务的实现,这就是模板方法模式的好处。可以封装变与不变,将不变的固化在高层,隐藏其细节。
        private void boilWater() {
            System.out.println("将水煮沸");
        }
    
        private void pourInCup() {
            System.out.println("将饮料倒入杯中");
        }
    
        /*
         * 泡制饮料brew()和加入调料品addCondiments()这两个方法我们不知道它们在算法框架中的具体实现,因此定义为抽象方法,
         * 我们用protected进行修饰, 在子类中可见便于进行重写。
         */
        protected abstract void brew();
    
        protected abstract void addCondiments();
    
    }

    具体子类延迟实现步骤 Coffee

    package com.pattern.template;
    
    /**
     * 提供制备咖啡的具体实现子类。 具体子类实现延迟步骤,满足特定的业务需求。
     * 
     *
     */
    public class Coffee extends RefreshBeverage {
    
        protected void brew() {
            System.out.println("步骤二 用沸水冲泡咖啡");
        }
    
        protected void addCondiments() {
            System.out.println("步骤四 加入糖和牛奶");
        }
    
    }

    钩子使子类更灵活 Tea

    package com.pattern.template;
    
    public class Tea extends RefreshBeverage {
    
        protected void brew() {
            System.out.println("步骤二 用80度热水浸泡茶叶5分钟");
        }
    
        protected void addCondiments() {
            System.out.println("步骤四 加入柠檬");
        }
    
        protected boolean isCustomerWantsCondiments() {
            return false;
        }
    
    }

    测试类 RefreshBeverageTest

    package com.pattern.template;
    
    public class RefreshBeverageTest {
    
        public static void main(String[] args) {
            System.out.println("制备咖啡中······");
            RefreshBeverage b1 = new Coffee();
            b1.prepareBeverageTemplate();
            System.out.println("咖啡好了········");
    
            // 制备茶的测试代码
            System.out.println("
    *********************************");
            System.out.println("制备茶水中······");
            RefreshBeverage b2 = new Tea();
            b2.prepareBeverageTemplate();
            System.out.println("茶水好了······");
        }
    
    }
  • 相关阅读:
    【Git】Git入门
    前端基础(三)
    从技术体系到商业洞察,中小研发团队架构实践之收尾篇 arch
    Node+Vue
    LinuxShell编程
    Selenium之用xpath定位元素
    Python之Unittest记录
    SQL中表的连接类型左连接、右连接、内连接
    插入排序 | 选择排序 | 冒泡排序
    5tu1
  • 原文地址:https://www.cnblogs.com/zengxiaoliang/p/8110339.html
Copyright © 2020-2023  润新知