模板模式(Template Pattern)

本文章参考:http://meigesir.iteye.com/blog/1506484

模板模式(Template Pattern)

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

我们使用冲咖啡喝冲茶叶的过程来讲解模板模式。假设冲咖啡和冲茶叶的流程是这样的:

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

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


Java实践:

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

public abstract class Beverage {

    /**
     * 冲泡咖啡或茶的流程
     */
    public final void create() {
        boilWater();//把水煮沸
        brew();//用沸水冲泡
        pourInCup();//倒进杯子
        addCoundiments();//加糖或其它

    }

    public void boilWater() {
        System.out.println("煮开水");
    }

    public abstract void brew();

    public void pourInCup() {
        System.out.println("倒进杯子");
    }

    public abstract void addCoundiments();
}


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

①咖啡(Coffee)

public class Coffee extends Beverage {

    /** 
     * @see com.study.templatepattern.Beverage#brew()
     */
    @Override
    public void brew() {
        System.out.println("用水冲咖啡");
    }

    /** 
     * @see com.study.templatepattern.Beverage#addCoundiments()
     */
    @Override
    public void addCoundiments() {
        System.out.println("添加糖和牛奶");
    }

}

②茶(Tea)

public class Tea extends Beverage {

    /** 
     * @see com.study.templatepattern.Beverage#brew()
     */
    @Override
    public void brew() {
        System.out.println("用水冲茶");
    }

    /** 
     * @see com.study.templatepattern.Beverage#addCoundiments()
     */
    @Override
    public void addCoundiments() {
        System.out.println("添加蜂蜜");
    }

}

写一个类测试:

public static void main(String[] args) {
        Coffee coffee = new Coffee();
        coffee.create();
        System.out.println("-----------------------------");
        Tea tea = new Tea();
        tea.create();
    }

运行结果:

煮开水
用水冲咖啡
倒进杯子
添加糖和牛奶
------------
煮开水
用水冲茶
倒进杯子
添加蜂蜜

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

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

1>先对模板类Beverage进行修改

public abstract class Beverage {

    /**
     * 冲泡咖啡或茶的流程
     */
    public final void create() {
        boilWater();//把水煮沸
        brew();//用沸水冲泡
        pourInCup();//倒进杯子
        addCoundiments();//加糖或其它
        hook();//挂钩
    }

    //空实现方法
    public void hook() {
    }

    public void boilWater() {
        System.out.println("煮开水");
    }

    public abstract void brew();

    public void pourInCup() {
        System.out.println("倒进杯子");
    }

    public abstract void addCoundiments();
}



2>假设咖啡店搞活动,和一杯咖啡送一杯,修改咖啡(Coffee)类

public class Coffee extends Beverage {

    /** 
     * @see com.study.templatepattern.Beverage#brew()
     */
    @Override
    public void brew() {
        System.out.println("用水冲咖啡");
    }

    /** 
     * @see com.study.templatepattern.Beverage#addCoundiments()
     */
    @Override
    public void addCoundiments() {
        System.out.println("添加糖和牛奶");
    }

    /** 
     * @see com.study.templatepattern.Beverage#hook()
     */
    @Override
    public void hook() {
        System.out.println("再来一杯");
    }

}


这样在运行结果中有“再来一杯”

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

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

public abstract class Beverage {

    /**
     * 冲泡咖啡或茶的流程
     */
    public final void create() {
        boilWater();//把水煮沸
        brew();//用沸水冲泡
        pourInCup();//倒进杯子

        if (hook()) {
            addCoundiments();//加糖或其它
        }
    }

    public boolean hook() {
        return true;
    }

    public void boilWater() {
        System.out.println("煮开水");
    }

    public abstract void brew();

    public void pourInCup() {
        System.out.println("倒进杯子");
    }

    public abstract void addCoundiments();
}

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

public class Coffee extends Beverage {

    /** 
     * @see com.study.templatepattern.Beverage#brew()
     */
    @Override
    public void brew() {
        System.out.println("用水冲咖啡");
    }

    /** 
     * @see com.study.templatepattern.Beverage#addCoundiments()
     */
    @Override
    public void addCoundiments() {
        System.out.println("添加糖和牛奶");
    }

    /** 
     * @see com.study.templatepattern.Beverage#hook()
     */
    @Override
    public boolean hook() {
        return false;
    }

}

这样在运行结果中没有添加配料。


关于模板模式

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

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

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

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值