Java 设计模式-模板方法

江湖中流传无招胜有招,飞花摘叶可伤人,那是高手的化境。但要成为高手,必须从基础开始。所谓招式,或势大力沉,或快速机巧,或出人意料,都是有迹可寻。

对于软件,对于JAVA自也有前辈高手,或归纳,或原创,或借鉴,汇成了一些套路,程序员称之为模式。

就先学习下模板方法吧

引子

中国人好饮茶,老外爱coffee.

要泡茶,一般经过以下4个步骤

1.烧水

2.开水倒进茶杯

3.放茶叶,开始泡茶

4.茶水里加柠檬(年轻人喜欢这么干)

看看Tea类

/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:22
 */
public class Tea {

    /**
     * 烧水
     */
    public void boilWater() {
        System.out.println("Boiling water");
    }

    /**
     * 将开水倒进杯子
     */
    public void pourInCup() {
        System.out.println("pour water into a Cup");
    }

    /**
     * 将茶叶浸泡
     */
    public void SteepingToBag() {
        System.out.println("Steeping the tea");
    }

    /**
     * 加柠檬
     */
    public void addLemon() {
        System.out.println("Adding lemon");
    }
}

原料有了,怎么泡呢,恩,应该有个方法来控制泡茶流程

/**
     * 泡茶
     */
    void prepareRecipe() {
        boilWater();
        pourInCup();
        SteepingToBag();
        addLemon();
    }

要喝咖啡,一般经过以下4个步骤

1.烧水

2.开水倒进茶杯

3.把咖啡倒进杯子

4.咖啡里加糖或牛奶(老外都喜欢?)

再看看Coffee

/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:12
 */
public class Coffee {


    /**
     * 烧水
     */
    public void boilWater() {
        System.out.println("Boiling water");
    }

    /**
     * 将开水倒进杯子
     */
    public void pourInCup() {
        System.out.println("pour water into a Cup");
    }

    /**
     * 把咖啡倒进杯子
     */
    public void brewCofferGrinds() {
        System.out.println("Dripping Coffee through filter");
    }

    /**
     * 加糖和牛奶
     */
    public void addSugarAndMilk() {
        System.out.println("Adding sugar and milk");
    }
}

现在加个控制冲咖啡的方法

void prepareRecipe() {
        boilWater();
        pourInCup();
        brewCofferGrinds();
        addSugarAndMilk();
    }

恩,有发现了,上面有一样的步骤

1.烧水

2.开水倒进茶杯

那说明产生了重复代码,我们一般会这么干,提取公用方法,生成基类,类似如下 

/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:33
 */
public class AbstractCoffineBeverage {

    /**
     * 烧水
     */
    void boilWater() {
        System.out.println("Boiling water");
    }

    /**
     * 将开水倒进杯子
     */
    void pourInCup() {
        System.out.println("pour water into a Cup");
    }
}

Tea和Coffee继续这个基类,恩。这样好像还不错,还能进一步吗,能吗?


泡茶和冲咖啡都是4步,看下不一样的2步

泡茶:是把茶叶放进杯子里泡,咖啡:把咖啡放进杯子冲

泡茶:加柠檬;咖啡:加糖加牛奶。闻到了什么,对,其实他们步骤也是一样的,所以控制的流程方法应该是一样的

prepareRecipe

那么,我们的基类可以这样

/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:33
 */
public abstract class AbstractCoffineBeverage2 {

    /**
     * 烧水
     */
    void boilWater() {
        System.out.println("Boiling water");
    }

    /**
     * 将开水倒进杯子
     */
    void pourInCup() {
        System.out.println("pour water into a Cup");
    }

    public abstract void brew();

    public abstract void addCondiments();

}

基类做为抽象类,并且重新命名一个brew,addCondiments方法,分别表示冲泡与添加调料,那么控制的泡茶,冲咖啡的方法就是一个公用的了,子类不能改变它的流程

    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();

    }

而此时对应的Tea和Coffee变成如下 

/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:12
 */
public class Coffee extends AbstractCoffineBeverage {

    @Override
    public void brew() {
        System.out.println("Dripping Coffee through filter");
    }


    @Override
    public void addCondiments() {
        System.out.println("Adding sugar and milk");
    }


}
/**
 * @copyright remark holdings
 */
package com.proxy.proxya.design.template;

/**
 * @author kobe_t
 * @date 2018/2/15 22:22
 */
public class Tea extends AbstractCoffineBeverage {


    @Override
    public void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    public void addCondiments() {
        System.out.println("Adding lemon");
    }
}

那么我们泡茶和冲咖啡的流程就统一了,

要泡茶

Tea tea = new Tea();
        tea.prepareRecipe();
        System.out.println();

输出

Boiling water
Steeping the tea
pour water into a Cup
Adding lemon

冲咖啡

Coffee coffee = new Coffee();
        coffee.prepareRecipe();

输出

Boiling water
Dripping Coffee through filter
pour water into a Cup
Adding sugar and milk

Ok,这就是模板方法:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值