模板方法模式

模板方法模式定义为 一个方法定义了一个算法的骨架或者步骤,而将一些步骤延迟子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤。
模板方法在基类中定义了一个操作的流程顺序,能够保证该步骤按序进行,有一些步骤的具体实现在基类中已经声明,而将一些变化的步骤的具体实现交给了子类去实现,从而就达到了延迟一些步骤到子类中,模板方法一个最大的好处就是能够设定一个业务流程能够按照一定严格的顺序执行,控制了整个算法的执行步骤。
这个方法将算法定义成一组步骤,其中凡是想让子类进行自定义实现的步骤,均定义为抽象方法。抽象基类的特点是,一般将模板方法设置为final,这样防止子类覆盖该算法的步骤,将一些相同的操作或步骤直接在基类中实现,将一些变化的步骤设置为抽象由子类去完成。
代码实例
假如要泡杯茶和咖啡,要想泡咖啡则需要先将水煮沸,然后用沸水冲泡咖啡,将咖啡倒进杯子,加糖和牛奶。要想泡茶叶则需要把水煮沸,然后用沸水冲茶叶,将茶倒入杯子,放点柠檬。
通过分析,这些操作基本上都是四步骤,顺序都是固定的,且有相同的步骤,则就可以利用模板方法来将泡饮料的过程制作一个算法的骨架,将变化的部分抽象出来,让具体的子类去实现。
抽象超类,这个类是负责泡饮料的基类,设置了算法的骨架
package com.whut.modelmethod;
//模板方法
abstract  class BeverageMake {

//final可以防止子类更改覆盖该算法,这样可以保证算法步骤不被破坏
public  final  void prepareRecipe()
{
boilWater();
brew();
pourInCup();
addCondiments();
}

abstract  void brew();
abstract  void addCondiments();
//烧水
public void boilWater()
{
System.out.println( "Now start to boiling water");
}
//饮料导入杯子汇总
public void pourInCup()
{
System.out.println( "pour the beverage into the cup");
}
}
具体的类,茶叶类:
package com.whut.modelmethod;

public class Tea  extends BeverageMake {

@Override
void brew() {
// TODO Auto-generated method stub
System.out.println( "boil the tea in the water");
}

@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println( "put some condiments into the tea");
}

}
测试类:
package com.whut.modelmethod;

public class MakeTest {

public static void main(String[] args) {
Tea tea= new Tea();
tea.prepareRecipe();
}
}
模板方法中挂钩:
当在模板方法中某一些步骤是可选的时候,也就是该步骤不一定要执行,可以由子类来决定是否要执行,则此时就需要用上钩子。钩子是一种被声明在抽象类中的方法,但一般来说它只是空的或者具有默认值,子类可以实现覆盖该钩子,来设置算法步骤的某一步骤是否要执行。钩子可以让子类实现算法中可选的部分,让子类能够有机会对模板方法中某些一即将发生的步骤做出反应。
重写上面的代码
这次茶叶泡好后,加不加东西由子类去决定
超类
package com.whut.modelmethod;
//模板方法
abstract class BeverageMake {

//final可以防止子类更改覆盖该算法,这样可以保证算法步骤不被破坏
public  final  void prepareRecipe()
{
boilWater();
brew();
pourInCup();
if(hookCondiments())
addCondiments();
}

abstract  void brew();
abstract  void addCondiments();
//烧水
public  void boilWater()
{
System.out.println( "Now start to boiling water");
}
//饮料导入杯子汇总
public  void pourInCup()
{
System.out.println( "pour the beverage into the cup");
}

//加入了钩子,来让子类决定是否执行该步骤
public  boolean hookCondiments()
{
return true;
}
}
茶叶子类:
package com.whut.modelmethod;

public class Tea  extends BeverageMake {

@Override
void brew() {
// TODO Auto-generated method stub
System.out.println( "boil the tea in the water");
}

@Override
void addCondiments() {
// TODO Auto-generated method stub
System.out.println( "put some condiments into the tea");
}

//设置不需要加饮料,这样就可以控制算法的某一个步骤不执行
@Override
public  boolean hookCondiments()
{
return  false;
}
}
设计原则:
别调用我们,我来调用你们。
这种原则主要就是,我们允许底层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎么样来使用这些底层组件
要点:
1)钩子是一种方法,它在抽象类中不做事,或者是默认的事情,子类可以选择覆盖它
2)为了防止子类改变模板方法中的算法骨架,一般将模板方法声明为final
3)策略模式和模板方法都是用于封装算法,前者是利用组合和委托模型,而后者则是继承
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值