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


    模板方法 模式

    定义: 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

    一个例子

    假设有咖啡和茶两个类:

    public class Coffee {
        void prepareRecipe() {
            // 1. 烧水
            boilWater();
            // 2. 用沸水冲泡咖啡
            brewCoffeeGrinds();
            // 3. 把咖啡倒进杯子
            pourInCup();
            // 4. 加糖和牛奶
            addSugarAndMilk();
        }
        private void addSugarAndMilk() {
            System.err.println("加柠檬");
        }
    
        private void pourInCup() {
            System.err.println("茶倒入杯子里");
        }
    
        private void brewCoffeeGrinds() {
            System.err.println("冲泡咖啡");
        }
    
        private void boilWater() {
            System.err.println("将水煮沸");
        }
    }
    
    package com.gitlearning.hanldegit.patterns.template.before;
    
    public class Tea {
        /**
         * 沏茶的整个过程
         */
        void prepareRecipe() {
            // 1. 烧水
            boilWater();
            // 2. 浸泡茶叶(不是越狱中的T-bag哦)
            steepTeaBag();
            // 3. 把茶倒入杯子
            pourInCup();
            // 4. 加柠檬
            addLemon();
        }
    
        private void addLemon() {
            System.err.println("加柠檬");
        }
    
        private void pourInCup() {
            System.err.println("茶倒入杯子里");
        }
    
        private void steepTeaBag() {
            System.err.println("浸泡茶叶");
        }
    
        private void boilWater() {
            System.err.println("将水煮沸");
        }
    }
    
    

    我们发现沏茶和冲咖啡的过程有些是一样的,有些不一样。

    prepareRecipe作为模板方法,抽取一个抽象类:

    package com.gitlearning.hanldegit.patterns.template.after;
    
    // 咖啡因饮料
    public abstract class CaffeineBeverage {
        void prepareRecipe() {
            // 1. 烧水
            boilWater();
            // 2. 冲泡
            brew();
            // 3. 倒进杯子
            pourInCup();
            // 4. 加料
            addCondiments();
        }
    
        protected abstract void addCondiments() ;
    
        private void pourInCup() {
            System.err.println("茶倒入杯子里");
        }
    
        protected abstract void brew() ;
    
        private void boilWater() {
            System.err.println("将水煮沸");
        }
    }
    
    

    Caffee和Tea继承该抽象类,并实现各自的brew和addCondiments方法。

    package com.gitlearning.hanldegit.patterns.template.after;
    
    public class Coffee extends CaffeineBeverage {
        @Override
        protected void addCondiments() {
            System.err.println("加奶和糖");
        }
    
        @Override
        protected void brew() {
            System.err.println("冲泡咖啡");
        }
    }
    
    
    package com.gitlearning.hanldegit.patterns.template.after;
    
    public class Tea extends CaffeineBeverage {
        @Override
        protected void addCondiments() {
            System.err.println("加柠檬");
        }
    
        @Override
        protected void brew() {
            System.err.println("浸泡茶叶");
        }
    }
    
    

    至此,使用模板方法模式解决两个类的冗余代码已经解决。

    模板方法的使用

    Java中使用到模板方法的地方:

    AQS:acquire,release,acquireShared,releaseShared,里面调用子类方法tryAcquire,tryRelease,tryAcquireShared,tryReleaseShared。

    InputStream:public int read(byte b[], int off, int len) throws IOException调用了read()方法,read方法由子类实现

    其他

    1. github上的patterns.template包下面另外写了个参照AQS的写法,里面新增了beforeExecute()方法和afterExecute()钩子方法,钩子方法可以用来做一些日志记录或者性能测试相关的一些操作。

    2. 模板方法经常用在框架里,超类给定方法,具体实现由子类完成。

    3. 模板方法定义了算法步骤,并将实现延迟到子类

    4. 模板方法提供了一种代码复用的重要技巧

    5. 模板方法抽象类可以定义具体方法/抽象方法/钩子方法,钩子可以不做事,或default,子类可以选择是否覆写

    6. 模板方法模式和策略模式都封装算法,一个用组合,一个用继承

    7. 好莱坞原则:别调用我们,我们会调用你。模板方法的抽象类来调用子类的方法实现。

    8. 工厂方法是模板方法的一种特殊版本。

    当你准备好了,机会来临的时候,你才能抓住
  • 相关阅读:
    连接池的实现 redis例子
    XSS的防御
    element-UI使用中:el-input type为textarea时@change无法触发?
    textarea高度自适应(转载)
    友盟统计单页面应用vue
    axios formData提交数据 && axios设置charset无效???
    解锁技能:sass + node-sass多页面应用编译(转载)
    css3新单位vw、vh、vmin、vmax的使用详解(转载)
    移动端bug集合
    Python3之Memcache使用
  • 原文地址:https://www.cnblogs.com/studentytj/p/11295729.html
Copyright © 2020-2023  润新知