「聊设计模式」之模板方法模式(Template Method)


本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶,欢迎持续关注&&收藏&&订阅!


前言

  在软件开发中,设计模式是经典的解决方案,它们被广泛应用于面向对象的程序设计中。其中,模板方法模式(Template Method)是一种常用的行为型设计模式,它定义一个操作中的算法骨架,而将一些步骤延迟到子类中实现。本文将从原理、实现以及应用场景三个方面来介绍模板方法模式。

摘要

  模板方法模式是一种基于继承的设计模式,它通过抽象父类定义一系列的抽象方法和模板方法,而由具体的子类来实现这些抽象方法,从而完成对算法的具体实现。模板方法模式遵循“开闭原则”,能够很好地解决代码复用、扩展性和屏蔽细节等问题。

模板方法模式

模式概念

  模板方法模式是一种行为型设计模式,它定义一个算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。它通过将相同的代码抽象到父类中来避免代码重复和复杂性,而通过子类的扩展来实现算法的不同变化。模板方法模式是一种可扩展性很强的模式,因为它使用了多态性和继承来实现不同的算法变化。模板方法模式在软件开发中广泛应用于框架开发、算法设计和复杂业务逻辑的实现。

模式结构

模板方法模式的结构包括以下几个角色:

  1. 抽象类(Abstract Class):定义了一系列抽象方法和模板方法。其中模板方法定义了算法的骨架,而抽象方法则需要子类去实现。

  2. 具体类(Concrete Class):实现了抽象类中定义的抽象方法,完成算法中具体的步骤。同时,它还可以重写模板方法中的某些步骤,来实现算法的变化。

通过这种方式,模板方法模式将算法的具体实现推迟到具体子类中,从而实现了算法的复用和扩展。

如下是模板方法模式的UML类图:

「聊设计模式」之模板方法模式(Template Method)_第1张图片

模式优缺点

优点

1.模板方法模式提供了一种代码复用的方式,将实现相同或类似的方法抽象到父类中,减少了代码的重复性。
2.模板方法模式提供了一种易于维护的方式,由于具体实现都在父类中,所以在需要修改时只需要在父类中修改即可,不需要修改每个子类。
3.模板方法模式提高了代码的灵活性,通过抽象出一些方法,可以方便地扩展子类功能。

缺点

1.在父类中定义了抽象方法,要求子类实现,如果父类的AbstractClass在设计时不够完善,或者需要修改时,会对所有的子类造成影响。
2.模板方法模式降低了程序的灵活性,当父类增加新的抽象方法时,所有子类都必须进行修改,否则编译会出错。

应用场景

模板方法模式适用于以下场景:

  • 在多个类中存在相似的算法,但具体实现不同的情况下,可以使用模板方法模式将算法的公共部分抽象出来,由子类实现不同的具体实现。
  • 当需要控制子类的扩展时,可以使用模板方法模式。模板方法模式通过定义抽象类来规范子类的方法实现,子类必须遵从抽象类中定义的方法的规范,这样可以控制子类的扩展。
  • 如果需要一次性编写出框架的核心代码,而将具体实现留给子类来实现,可以使用模板方法模式。

模式代码实现

  下面通过一个简单的示例来说明模板方法模式的实现。

  假设我们需要开发一个系统,实现计算机基准测试的功能。我们可以定义一个Benchmark类来表示基准测试,其中包括start()run()stop()三个抽象方法,分别用于启动测试、执行测试和结束测试。具体的测试算法可以由子类来实现。

package com.example.javaDesignPattern.templateMethod;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/20 15:44
 */
public abstract class Benchmark {
    public void runBenchmark() {
        start();
        for (int i = 0; i < 10; i++) {
            run();
        }
        stop();
    }

    public abstract void start();

    public abstract void run();

    public abstract void stop();
}

我们可以定义一个具体的子类来实现具体的测试算法,如下所示:

package com.example.javaDesignPattern.templateMethod;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/20 15:44
 */
public class ConcreteBenchmark extends Benchmark {
    @Override
    public void start() {
        System.out.println("启动基准测试");
    }

    @Override
    public void run() {
        System.out.println("执行基准测试");
    }

    @Override
    public void stop() {
        System.out.println("结束基准测试");
    }
}

  其中定义了一个基准测试的抽象类Benchmark,其中包含了一个模板方法,模板方法定义了基本操作的顺序和流程,具体的操作由子类实现。

  具体的子类ConcreteBenchmark重写了三个抽象方法startrunstop,其中start方法启动了基准测试,run方法执行了基准测试,stop方法结束了基准测试。

  在具体的子类中,可以实现具体的基准测试,而模板方法中定义的流程保证了基准测试的正确性和可维护性。这种设计模式可以减少代码重复,提高代码的可读性和可维护性。

  然后你在使用时,我们可以先创建一个Benchmark对象,然后调用它的runBenchmark()方法,即可执行具体的测试算法。

package com.example.javaDesignPattern.templateMethod;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/20 15:45
 */
public class Client {
    public static void main(String[] args) {
        Benchmark benchmark = new ConcreteBenchmark();
        benchmark.runBenchmark();
    }
}

执行结果如下:

「聊设计模式」之模板方法模式(Template Method)_第2张图片

代码解读:

  如上代码,定义了一个名为Client的类,其中包含一个名为main的公共静态方法。当程序运行时,将创建一个ConcreteBenchmark对象,该对象实现了Benchmark接口,并将其赋值给类型为Benchmarkbenchmark变量。接下来,runBenchmark方法将被调用来执行基准测试。

附录源码

  如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

总结

  模板方法模式是一种基于继承的设计模式,它通过一系列抽象方法和模板方法来定义算法骨架,而由具体的子类来实现这些抽象方法,从而完成对算法的具体实现。模板方法模式可以很好地解决代码复用、扩展性和屏蔽细节等问题。在实际应用中,模板方法模式比较常用,比如在框架设计、算法设计等方面都有广泛的应用。

☀️建议/推荐你


  如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

关于我


我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

你可能感兴趣的:(《聊设计模式》,设计模式,模板方法模式,Template,Method,Java)