美文网首页程序员
Java 设计模式(9) —— 模板模式

Java 设计模式(9) —— 模板模式

作者: 磊_lei | 来源:发表于2018-05-13 21:42 被阅读210次

    一、模板模式

    封装了一个算法步骤,并允许子类为一个或多个步骤方法提供实现。模板模式可以使子类在不改变算法结构的情况下,重新定义算法中的某些步骤。

    模板模式

    二、示例

    泡咖啡与泡茶:

    • 泡咖啡的步骤:
      • 水烧开
      • 冲泡咖啡粉
      • 把咖啡倒入杯子
      • 加糖和牛奶
    • 泡茶步骤:
      • 水烧开
      • 冲泡茶叶
      • 把茶水倒入杯子
      • 加柠檬

    面向对象模式的示例:

    1.定义泡咖啡的方法类

    
    /**
     * 面向对象方法对象,泡咖啡,按固定流程走完
     */
    public class Coffee {
    
        /**
         * 泡咖啡
         */
        public void prepareRecipe() {
            boilWater();
            brewCoffee();
            pourInCup();
            addSugarMilk();
        }
    
    
        /**
         * 煮开水
         */
        public void boilWater() {
            System.out.println("Boiling water");
        }
    
    
        /**
         * 放咖啡粉
         */
        public void brewCoffee() {
            System.out.println("Brewing coffee");
        }
    
        /**
         * 放进杯子里
         */
        public void pourInCup() {
            System.out.println("Pouring into cup");
        }
    
        /**
         * 添加糖和奶
         */
        public void addSugarMilk() {
            System.out.println("Adding sugar or milk");
        }
    }
    

    2.定义泡茶的方法类

    
    /**
     * 面向对象,泡茶,按固定流程走完
     */
    public class Tea {
    
    
        /**
         * 泡茶
         */
        public void prepareRecipe() {
            boilWater();
            brewTea();
            pourInCup();
            addLemon();
        }
    
    
        /**
         * 煮开水
         */
        public void boilWater() {
            System.out.println("Boiling water");
        }
    
    
        /**
         * 放茶叶
         */
        public void brewTea() {
            System.out.println("Brewing tea");
        }
    
        /**
         * 放进杯子里
         */
        public void pourInCup() {
            System.out.println("Pouring into cup");
        }
    
        /**
         * 添加柠檬
         */
        public void addLemon() {
            System.out.println("Adding lemon");
        }
    
    
    }
    
    

    3.调用方法

    
    /**
     * 面向对象模式,调用对象内提供的方法
     */
    public class MainTest {
    
    
        public static void main(String[] args) {
            Coffee coffee = new Coffee();
            Tea tea = new Tea();
    
            coffee.prepareRecipe();
            tea.prepareRecipe();
        }
    
    }
    
    

    三、模板模式

    • 泡咖啡和泡茶的方法步骤都是固定的,只是用到的材料不同,因此可以将泡饮料的方式定义成一个固定的模板

      • 1.水烧开
      • 2.冲泡饮料
      • 3.把饮料倒入杯子
      • 4.添加附属配料
    • 模板模式即对固定流程模式的操作进行模板化,实现固定的内部方法,抽象出具体的方法,并且可以设置动态的条件

      • AbstractClass
      • AbstractMethod
      • ConcreteClass
      • Hook

    1.定义模板方法

    
    /**
     * 模板模式,制定操作流程,定义抽象方法和具体实现的方法
     */
    public abstract class HotDrink {
    
        public final void prepareRecipe() {
            boilWater();
            brew();
            pourInCup();
            if (addCondimentsHook()) {
                addCondiments();
            }
        }
    
        /**
         * 煮开水是通用的固定方法
         */
        public final void boilWater() {
            System.out.println("Boiling water");
        }
    
        /**
         * 添加原材料是抽象的实现的方法
         */
        public abstract void brew();
    
    
        /**
         * 放进杯子里是通用的固定方法
         */
        public final void pourInCup() {
            System.out.println("Pouring into cup");
        }
    
    
        /**
         * 添加配料是抽象的需要实现的方法
         */
        public abstract void addCondiments();
    
        /**
         * 动态变换的条件
         */
        public boolean addCondimentsHook() {
            return true;
        }
    
    }
    

    2.继承模板类,重写具体的自定义方法

    
    /**
     * 模板模式,咖啡对象,集成模板方法,实现具体方法
     */
    public class Coffee extends HotDrink {
    
        @Override
        public void brew() {
            System.out.println("Brewing coffee");
        }
    
        @Override
        public void addCondiments() {
            System.out.println("Adding sugar or milk");
        }
    
    }
    
    
    
    /**
     * 模板模式,泡茶对象,集成父类的必须方法,自定义实现具体方法
     */
    public class Tea extends HotDrink {
    
        @Override
        public void brew() {
            System.out.println("Brewing tea");
        }
    
        @Override
        public void addCondiments() {
            System.out.println("Adding lemon");
        }
    
        /**
         * 自定义的条件,是否需要添加辅料
         * @return boolean
         */
        @Override
        public boolean addCondimentsHook() {
            return false;
        }
    }
    
    

    3.具体调用

    
    /**
     * 模板模式,抽象类制定模板流程,定义抽象方法和具体方法
     */
    public class MainTest {
    
        public static void main(String[] args) {
            HotDrink coffee = new Coffee();
            HotDrink tea = new Tea();
    
            coffee.prepareRecipe();
            tea.prepareRecipe();
        }
    
    }
    
    

    模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

    三、好莱坞原则

    好莱坞原则:不要给我们打电话,我们会给你打电话

    • 高层无需知道调用底层的细节,解耦
    • 降低业务和框架的耦合
    • 业务组件可复用,可插拔

    四、总结

    1. 具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法整体结构。

    2. 代码复用的基本技术,在数据库设计中尤为重要。

    3. 存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则”。

    Java设计模式所有示例代码,持续更新中

    相关文章

      网友评论

        本文标题:Java 设计模式(9) —— 模板模式

        本文链接:https://www.haomeiwen.com/subject/myqrdftx.html