zoukankan      html  css  js  c++  java
  • 设计模式:模版模式(Template Pattern)

    android中的Activity框架,View框架中大量的on函数基本上都应用到了Template模式,掌握这一模式对于理解这些框架大有裨益。

    模版模式

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

    我们使用冲泡咖啡和冲泡茶的例子

    加工流程:

    咖啡冲泡法:1.把水煮沸、2.用沸水冲泡咖啡、3.把咖啡倒进杯子、4.加糖和牛奶

    茶冲泡法:   1.把水煮沸、2.用沸水冲泡茶叶、3.把  茶 倒进杯子、4.加蜂蜜

    实践步骤:

    1>创建一个模板(抽象)类:Beverage(饮料)

    Java代码

    package com.kaishengit.beverage;
    
    public abstract class Beverage {
        /**
         * 冲泡咖啡或茶...流程
         */
        public final void create(){
            boilWater();//把水煮沸
            brew();//用沸水冲泡...
            pourInCup();//把...倒进杯子
            addCoundiments();//加...
        }
    
    
        public abstract void addCoundiments();
    
        public abstract void brew();
        
        public void boilWater() {
            System.out.println("煮开水");
        }
        
        public void pourInCup() {
            System.out.println("倒进杯子");
        }
    }

    2>创建一个咖啡类(Coffee)和茶(Tea)类,都继承Beverage抽象类

    1.咖啡(Coffee)

    Java代码

    package com.kaishengit.beverage;
    
    public class Coffee extends Beverage{
    
        @Override
        public void addCoundiments() {
            System.out.println("添加糖和牛奶");    }
    
        @Override
        public void brew() {
            System.out.println("用水冲咖啡");
        }
    }

    2.茶(Tea)

    Java代码

    package com.kaishengit.beverage;
    
    public class Tea extends Beverage{
    
        @Override
        public void addCoundiments() {
            System.out.println("添加蜂蜜");
        }
    
        @Override
        public void brew() {
            System.out.println("用水冲茶");
        }
    
    }

     3.我们测试一下:

    package com.kaishengit.beverage;
    
    public class Test {
        public static void main(String[] args) {
            Coffee coffee = new Coffee();
            coffee.create();//冲泡咖啡
            
            //Tea tea = new Tea();//冲泡茶
            //tea.create();
        }
    }

    运行结果:

    -----------------------------------

    煮开水

    用水冲咖啡

    倒进杯子

    添加糖和牛奶

    -----------------------------------

    在模版模式中使用挂钩(hook)

    存在一个空实现的方法,我们称这种方法为”hook”。子类可以视情况来决定是否要覆盖它。

    1>我们对模板类(Beverage)进行修改

    Java代码

    package com.kaishengit.beverage;
    
    public abstract class Beverage {
        /**
         * 冲泡咖啡或茶...流程
         */
        public final void create(){
            boilWater();//把水煮沸
            brew();//用沸水冲泡...
            pourInCup();//把...倒进杯子
            addCoundiments();//加...
            
            hook();//挂钩
        }
        //空实现方法
        public void hook(){}
    
        public abstract void addCoundiments();
    
        public abstract void brew();
        
        public void boilWater() {
            System.out.println("煮开水");
        }
        
        public void pourInCup() {
            System.out.println("倒进杯子");
        }
    }

     2>假如我们搞活动,喝一杯咖啡送一杯,修改咖啡(Coffee)类

    Java代码

    package com.kaishengit.beverage;
    
    public class Coffee extends Beverage{
    
        @Override
        public void addCoundiments() {
            System.out.println("添加糖和牛奶");    }
    
        @Override
        public void brew() {
            System.out.println("用水冲咖啡");
        }
        
        /**
         * 挂钩
         */
        @Override
        public void hook() {
            System.out.println("再来一杯");
        }
    
    }

     3>使用上面的测试类

    运行结果:

    --------------------------------

    煮开水

    用水冲咖啡

    倒进杯子

    添加糖和牛奶

    再来一杯

    --------------------------------

    结果中有“再来一杯”...

    我们也可以这样使用挂钩,让其决定里面的代码是否执行

    1>我们对模板类(Beverage)进行修改

    Java代码

    package com.kaishengit.beverage;
    
    public abstract class Beverage {
        /**
         * 冲泡咖啡或茶...流程
         */
        public final void create(){
            boilWater();//把水煮沸
            brew();//用沸水冲泡...
            pourInCup();//把...倒进杯子
            
            //挂钩决定是否添加配料
            if(hook()){
                addCoundiments();//加...
            }
            //hook();
        }
    
        /**
         * 默认添加配料
         * @return
         */
        public boolean hook() {
            return true;
        }
    
        //public void hook(){}
        
        public abstract void addCoundiments();
    
        public abstract void brew();
        
        public void boilWater() {
            System.out.println("煮开水");
        }
        
        public void pourInCup() {
            System.out.println("倒进杯子");
        }
    }

    2>我们对Coffee类进行修改,让其不添加配料

    Java代码

    package com.kaishengit.beverage;
    
    public class Coffee extends Beverage{
    
        @Override
        public void addCoundiments() {
            System.out.println("添加糖和牛奶");    }
    
        @Override
        public void brew() {
            System.out.println("用水冲咖啡");
        }
        
        /**
         * 有的客人不喜欢加配料
         */
        @Override
        public boolean hook() {
            return false;
        }
        
        /*@Override
        public void hook() {
            System.out.println("再来一杯");
        }
    */
    }

    3>还是使用上面的测试类

    运行结果:

    ------------------------------------------------------

    煮开水

    用水冲咖啡

    倒进杯子

    ------------------------------------------------------

    运行结果中没有添加配料

    关于模板模式

    1>模板模式定义了算法的步骤,把这些步骤的实现延迟到子类

    2>模板模式为我们提供了一个代码复用的技巧

    3>模板抽象类中可以定义具体方法、抽象方法和钩子方法

    4>为了防止子类改变模板中的算法,可以将模板方法声明为final

    5>钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择要不要实现它

    -----------end--------------

    本文转载自: http://meigesir.iteye.com/blog/1506484

  • 相关阅读:
    Nmap参数详解(含扫描参数原理解释)
    为什么服务器突然回复RST——小心网络中的安全设备
    Security+学习笔记
    《HTTPS权威指南》读书笔记——PKI
    [Android 搞机]Twrp 中清除 data 和搞机清除的区别
    [C语言学习笔记五]复合语句和操作符的区分
    [C语言学习笔记四]变量与系统的交互
    [C语言学习笔记三]格式化输出和输入
    [C语言学习笔记二] extern 函数的用法
    [C语言学习笔记一]基本构架和变量
  • 原文地址:https://www.cnblogs.com/prescheng/p/4940714.html
Copyright © 2011-2022 走看看