Java设计模式之模板方法

简介:
模板方法模式定义为 一个方法定义了一个算法的骨架或者步骤,而将一些步骤延迟子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某一些步骤。
模板方法在基类中定义了一个操作的流程顺序,能够保证该步骤按序进行,有一些步骤的具体实现在基类中已经声明,而将一些变化的步骤的具体实现交给了子类去实现,从而就达到了延迟一些步骤到子类中,模板方法一个最大的好处就是能够设定一个业务流程能够按照一定严格的顺序执行,控制了整个算法的执行步骤。
这个方法将算法定义成一组步骤,其中凡是想让子类进行自定义实现的步骤,均定义为抽象方法。抽象基类的特点是,一般将模板方法设置为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)策略模式和模板方法都是用于封装算法,前者是利用组合和委托模型,而后者则是继承



本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1167937
相关文章
|
10天前
|
算法 Java Linux
java制作海报二:java使用Graphics2D 在图片上合成另一个照片,并将照片切割成头像,头像切割成圆形方法详解
这篇文章介绍了如何使用Java的Graphics2D类在图片上合成另一个照片,并将照片切割成圆形头像的方法。
21 1
java制作海报二:java使用Graphics2D 在图片上合成另一个照片,并将照片切割成头像,头像切割成圆形方法详解
|
4天前
|
Java Apache Maven
Java将word文档转换成pdf文件的方法?
【10月更文挑战第13天】Java将word文档转换成pdf文件的方法?
12 1
|
7天前
|
Java 编译器
Java“返回类型为 void 的方法不能返回一个值”解决
在 Java 中,如果一个方法的返回类型被声明为 void,那么该方法不应该包含返回值的语句。如果尝试从这样的方法中返回一个值,编译器将报错。解决办法是移除返回值语句或更改方法的返回类型。
|
8天前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
17 2
|
8天前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
14 1
|
8天前
|
Java
让星星⭐月亮告诉你,Java synchronized(*.class) synchronized 方法 synchronized(this)分析
本文通过Java代码示例,介绍了`synchronized`关键字在类和实例方法上的使用。总结了三种情况:1) 类级别的锁,多个实例对象在同一时刻只能有一个获取锁;2) 实例方法级别的锁,多个实例对象可以同时执行;3) 同一实例对象的多个线程,同一时刻只能有一个线程执行同步方法。
9 1
|
12天前
|
Java 编译器
在Java中,关于final、static关键字与方法的重写和继承【易错点】
在Java中,关于final、static关键字与方法的重写和继承【易错点】
19 5
|
10天前
|
算法 Java Linux
java制作海报四:java BufferedImage 转 InputStream 上传至OSS。png 图片合成到模板(另一个图片)上时,透明部分变成了黑色
这篇文章主要介绍了如何将Java中的BufferedImage对象转换为InputStream以上传至OSS,并解决了png图片合成时透明部分变黑的问题。
20 1
|
10天前
|
存储 算法 Java
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题
这篇文章是关于如何在Java中使用Graphics2D的RenderingHints方法来提高海报制作的图像质量和文字清晰度,包括抗锯齿和解决文字不清晰问题的技术详解。
17 0
java制作海报六:Graphics2D的RenderingHints方法参数详解,包括解决文字不清晰,抗锯齿问题
|
12天前
|
Java 编译器 C语言
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
16 3