您的位置:首页 > 编程语言 > Java开发

Java 设计模式-模板方法

2018-02-16 16:32 597 查看
江湖中流传无招胜有招,飞花摘叶可伤人,那是高手的化境。但要成为高手,必须从基础开始。所谓招式,或势大力沉,或快速机巧,或出人意料,都是有迹可寻。
对于软件,对于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 milkOk,这就是模板方法:
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤,多体会,多揣摩,多实践,三多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: