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
相关文章
|
20天前
|
设计模式 算法 Java
Java中的设计模式:提升代码质量的秘诀
【8月更文挑战第23天】在Java开发中,设计模式是提高代码可读性、可维护性和扩展性的强有力工具。本文通过浅显易懂的语言和实际案例,探讨几种常见的设计模式及其在Java中的应用,旨在帮助开发者更好地理解并运用这些模式来优化自己的代码结构。
37 2
|
7天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
12天前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
25 5
|
13天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
30 2
|
13天前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
25 1
|
13天前
|
设计模式 Java
重构你的代码:探索Java中的混合、装饰器与组合设计模式
【8月更文挑战第30天】在软件开发中,设计模式为特定问题提供了结构化的解决方案,使代码更易理解、维护及扩展。本文将介绍三种常用的 Java 设计模式:混合模式、装饰器模式与组合模式,并附有示例代码展示实际应用。混合模式允许通过继承多个接口或抽象类实现多重继承;装饰器模式可在不改变对象结构的情况下动态添加新功能;组合模式则通过树形结构表示部分-整体层次,确保客户端处理单个对象与组合对象时具有一致性。
11 1
|
14天前
|
安全 Java 开发者
【技术咖必看】Java异常处理新境界:throws关键字,打造万无一失的方法签名!
【技术咖必看】Java异常处理新境界:throws关键字,打造万无一失的方法签名!
29 3
|
14天前
|
安全 Java 程序员
【程序猿逆袭指南】Java高手的秘密武器:throws关键字,让你的方法签名霸气侧漏!
【程序猿逆袭指南】Java高手的秘密武器:throws关键字,让你的方法签名霸气侧漏!
12 3
|
12天前
|
小程序 Java
【aspose-words】Aspose.Words for Java模板语法详细剖析
本文通过详细分析Aspose.Words for Java模板语法,介绍了使用条件块、变量和动态合并表格单元格三个常用模板标签,并结合实际案例进行演示。通过这三个标签的实操,帮助读者更好地掌握Aspose.Words的使用技巧。此外,还提供了官方文档链接以便进一步学习。
56 0
【aspose-words】Aspose.Words for Java模板语法详细剖析
|
15天前
|
Java Spring 容器
Java获取接口的所有实现类方法
这篇文章介绍了在Java中获取接口所有实现类的方法,包括使用JDK的ServiceLoader(SPI机制)和Spring Boot中的@Autowired自动注入及ApplicationContextAware接口两种方式。
37 1