自定义模板方法模式:定义的算法的骨架中的方法,虽然某些步骤推迟到子类中,下模板方法允许子类不能改变在的情况下,该算法的结构。算法重新定义某些步骤。
设计原则:不要给我们打电话。我会打电话给你。(像猎头与求职者,求职者并不需要招聘,搜索会发现,你只需要工作)坞原则
引用一个样例,一个店中有两饮料:咖啡和茶。他们的冲泡方法
第一步:都是要用沸水
第二步:用热水泡咖啡或茶
第三步:把饮料倒进杯子
第四步:在饮料中增加适当的调料
在上面的步骤中一、三是一样的,能够抽取出来放在基类中,二、四不一样,能够抽象出来,让子类去实现,下面是饮料抽象的父类,父类能够让未知的子类去做它本身可能完毕的不好或者根本完毕不了的事情。能够加一个钩子函数:custcomerWantsCondiments(),请子类去重写。
CoffeineBeverageWithHook.java
package com.dzt.template;
/**
* 因为有的客户有可能不须要调料,这时就须要让客户去选择是否来加入调料,须要
*
* @author Administrator
*
*/
public abstract class CoffeineBeverageWithHook {
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (custcomerWantsCondiments())
addCondiments();
}
abstract void brew(); // 冲泡
abstract void addCondiments(); // 加入调料
// 烧开水
void boilWater() {
System.out
.println("CoffeineBeverageWithHook-------------------->boilWater");
}
// 把饮料倒进杯子
void pourInCup() {
System.out
.println("CoffeineBeverageWithHook-------------------->pourInCup");
}
/**
* 子类能够重载这个函数
*
* @return
*/
boolean custcomerWantsCondiments() {
return true;
}
}
下面是咖啡类。继承了上面的饮料父类
CoffeineWithHook.java
package com.dzt.template;
public class CoffeineWithHook extends CoffeineBeverageWithHook {
@Override
void brew() {
// TODO Auto-generated method stub
System.out.println("CoffeineWithHook-------------------->brew");
}
@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out
.println("CoffeineWithHook-------------------->addCondiments");
}
@Override
boolean custcomerWantsCondiments() {
// TODO Auto-generated method stub
return false;
}
}
下面是茶类,继承了上面的饮料父类
TeaWithHook.java
package com.dzt.template;
public class TeaWithHook extends CoffeineBeverageWithHook {
@Override
void brew() {
// TODO Auto-generated method stub
System.out.println("TeaWithHook-------------------->brew");
}
@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println("TeaWithHook-------------------->addCondiments");
}
@Override
boolean custcomerWantsCondiments() {
// TODO Auto-generated method stub
return true;
}
}
以上代码能够去改动custcomerWantsCondiments()函数,由用户决定是否须要加入调料
測试代码
package com.dzt.template;
/**
* 模板方法模式 在模板方法中加入钩子方法。让用户决定
*
* @author Administrator
* @date 2014.08.20
*/
public class TemplateMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CoffeineWithHook coffHook = new CoffeineWithHook();
TeaWithHook teaHook = new TeaWithHook();
coffHook.prepareRecipe();
System.out
.println("---------------------------------------------------------------");
teaHook.prepareRecipe();
}
}
总结:
1、模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
2、模板方法导致一种方向控制结构,"好莱坞法则":"Don't call me,i will call you.",即一个父类调用子类的操作。而不是相反。
3、模板调用操作的类型有详细的操作,详细的AbstracClass操作,原语操作。工厂方法,钩子操作。少定义原语操作。
4、模板方法使用继承来改变算法的一部分。策略模式使用托付来改变整个算法。
参考书:《Head First 设计模式》
版权声明:本文博客原创文章,博客,未经同意,不得转载。