设计模式:模版模式(Template Pattern)-转

模版模式

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

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

加工流程:

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

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

一、创建一个创模板(抽象)类

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)

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)

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)进行修改

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)类

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)进行修改

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类进行修改,让其不添加配料

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>钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择要不要实现它

时间: 2024-12-09 16:49:32

设计模式:模版模式(Template Pattern)-转的相关文章

设计模式 - 模板方法模式(template method pattern) JFrame 详解

模板方法模式(template method pattern) JFrame 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), Java的JFrame使用模板方法模式, paint()是可以覆盖的方法,

设计模式 - 模板方法模式(template method pattern) Applet 详解

模板方法模式(template method pattern) Applet 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), applet就是一个能够在网页上面执行的小程序, applet有很多钩子(

设计模式 - 模板方法模式(template method pattern) 排序(sort) 详解

模板方法模式(template method pattern) 排序(sort) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式的一个主要的应用是排序(sort)算法. 对象的排列方式并不是完全相同, 所以需要排序(sort)算法compareTo()

设计模式 - 模板方法模式(template method pattern) 详解

模板方法模式(template method pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 模板方法模式(template method pattern): 在一个方法中定义一个算法的骨架, 而将一些步骤延迟到子类中. 模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤. 模板方法可以进行挂钩(hook), 钩子(hook)是一种被声明在抽象类中的方法, 但只有空的或者默认的实现. 钩子的存在, 可以让子类有能力

设计模式 - 代理模式(proxy pattern) 未使用代理模式 详解

代理模式(proxy pattern) 未使用代理模式 详解 本文地址: http://blog.csdn.net/caroline_wendy 部分代码参考: http://blog.csdn.net/caroline_wendy/article/details/37698747 如果需要监控(monitor)类的某些状态, 则需要编写一个监控类, 并同过监控类进行监控. 但仅仅局限于本地, 如果需要远程监控, 则需要使用代理模式(proxy pattern). 具体方法: 1. 类中需要提供

设计模式 - 迭代器模式(iterator pattern) Java 迭代器(Iterator) 详解

迭代器模式(iterator pattern) Java 迭代器(Iterator) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考迭代器模式(iterator pattern): http://blog.csdn.net/caroline_wendy/article/details/35254643 Java的标准库(util)中包含迭代器接口(iterator interface), import java.util.Iterator; 继承(

设计模式 - 外观模式(facade pattern) 详解

外观模式(facade pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 外观模式(facade pattern): 提供了一个统一的接口, 用来访问子系统中的一群接口. 外观定义了一个高层接口, 让子系统更容易使用. 外观模式包含三个部分: 1. 子系统: 子类, 单个复杂子类 或 多个子类; 2. 外观(facade)类: 把子系统设计的更加容易使用; 3. 客户: 只需要调用外观类. 与适配器模式(adapter pattern)的

设计模式 - 策略模式(Strategy Pattern) 具体解释

策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全部, 禁止转载, 如有须要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间能够相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族须要常常扩展新的功能, 为了使用父类比較灵活的加入子类, 把父类的行为写成接口(interface)的形式; 使用set()方法

设计模式 - 组合模式(composite pattern) 详解

组合模式(composite pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 组合模式: 允许你将对象组合成树形结构来表现"整体/部分"层次结构. 组合能让客户以一致的方法处理个别对象以及组合对象. 建立组件类(Component), 组合类(composite)和叶子类(leaf)继承组件类, 客户类(client)直接调用最顶层的组合类(composite)即可. 具体方法: 1. 组件类(component), 包含组合