设计模式六: 模板方法(Template Method)

简介: 简介模板方法属于行为型模式的一种.实现层面上, 在抽象类中定义了算法或流程的骨架, 将其中易变的部分延迟到子类实现, 也就是允许它的子类实现其中的某些步骤.模板方法适用于算法不变, 但算法中某些步骤有变化的场景, 例如Spring中JDBC事务操作,打开连接-->开启事务-->执行sql-->提交事务-->关闭连接, 每次操作均按照这个步骤进行, 变化的是执行的sql不一样.意图定义算法框架,并将一些步骤的实现延迟到子类实现。

简介

模板方法属于行为型模式的一种.

实现层面上, 在抽象类中定义了算法或流程的骨架, 将其中易变的部分延迟到子类实现, 也就是允许它的子类实现其中的某些步骤.

模板方法适用于算法不变, 但算法中某些步骤有变化的场景, 例如Spring中JDBC事务操作,打开连接-->开启事务-->执行sql-->提交事务-->关闭连接, 每次操作均按照这个步骤进行, 变化的是执行的sql不一样.

意图

定义算法框架,并将一些步骤的实现延迟到子类实现。

类图

模板方法

实现

一. 定义抽象类, 并将算法的骨架定义封装到方法,注意方法用final修饰,防止有人继承该类后对算法做恶意修改, 不变的步骤可以实现

/**
 * 磨坊
 */
public abstract class MillTemplate {

    /**
     * 模板方法,定义步骤
     */
    public final void produce(){
        //准备(可能是小麦,也可能是玉米)
        prepare();
        //开机器
        start();
        //包装
        packaging();
        //运输(可能水路也可能火车)
        transport();
    }

    //准备(可能是小麦,也可能是玉米)
    protected abstract void prepare();

    private void start(){
        System.out.println("启动机器, 开始研磨...");
    }

    private void packaging(){
        System.out.println("包装...");
    }

    //运输(可能水路也可能火车)
    protected abstract void transport(); 
}

二. 定义子类继承抽象类, 并实现抽象方法

/**
 * 玉米磨坊
 */
public class CoreMill extends MillTemplate {
    protected void prepare() {
        System.out.println("准备好玉米");
    }

    protected void transport() {
        System.out.println("火车运输");
    }
}
/**
 * 小麦磨坊
 */
public class WheatMill extends MillTemplate {

    protected void prepare() {
        System.out.println("准备好小麦");
    }

    protected void transport() {
        System.out.println("船运");
    }
}

三. 调用

public class TemplateTest {
    public static void main(String[] args) {
        MillTemplate millTemplate = new WheatMill();
        millTemplate.produce();

        millTemplate = new CoreMill();
        millTemplate.produce();
    }
}

四. 钩子方法, 钩子方法为模板的算法提供了更大灵活性, 子类可以根据钩子方法的结果控制一些步骤执行或不执行

我们在模板方法中增加钩子方法

...
/**
* 模板方法,定义步骤
*/
public final void produce(){
    //准备(可能是小麦,也可能是玉米)
    prepare();
    //开机器
    start();
    //包装
    packaging();

    //检查的钩子方法
    if(needRecheck()){
        recheck();
    }

    //运输(可能水路也可能火车)
    transport();
}
...
//钩子方法
protected boolean needRecheck(){
    return true;
}
//检查
private void recheck(){
    System.out.println("检查...");
}
...

子类重载钩子方法已达到控制算法某一步骤是否执行的目的

//WheatMill 中增加
@Override
protected boolean needRecheck(){
    return false;
}

总结

优点: 1. 封装了不变部分, 可变部分易于扩展;2. 便于代码重用,便于维护

缺点: 每个不同的实现都需要一个子类, 导致类数量增加, 系统过于庞大

相关文章
|
6月前
|
设计模式 算法 Java
模板方法--设计模式
模板方法--设计模式
49 0
|
6月前
|
设计模式 算法 Java
Java一分钟之-设计模式:策略模式与模板方法
【5月更文挑战第17天】本文介绍了策略模式和模板方法模式,两种行为设计模式用于处理算法变化和代码复用。策略模式封装不同算法,允许客户独立于具体策略进行选择,但需注意选择复杂度和过度设计。模板方法模式定义算法骨架,延迟部分步骤给子类实现,但过度抽象或滥用继承可能导致问题。代码示例展示了两种模式的应用。根据场景选择合适模式,以保持代码清晰和可维护。
113 1
|
6月前
|
设计模式 Java 容器
【设计模式】JAVA Design Patterns——Async Method Invocation(异步方法调用模式)
【设计模式】JAVA Design Patterns——Async Method Invocation(异步方法调用模式)
|
5月前
|
设计模式 算法
模板方法-大话设计模式
模板方法-大话设计模式
|
6月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
5月前
|
设计模式 存储 Java
JavaSE——面向对象高级二(2/4)-final关键字、常量、抽象类(认识抽象类、抽象类的好处、应用场景-模板方法设计模式)
JavaSE——面向对象高级二(2/4)-final关键字、常量、抽象类(认识抽象类、抽象类的好处、应用场景-模板方法设计模式)
28 0
|
6月前
|
设计模式
设计模式(二)工厂方法模式(Factory Method)
设计模式(二)工厂方法模式(Factory Method)
35 0
|
6月前
|
设计模式 算法 Java
【设计模式】springboot3项目整合模板方法深入理解设计模式之模板方法(Template Method)
【设计模式】springboot3项目整合模板方法深入理解设计模式之模板方法(Template Method)
|
18天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。