设计模式(十五)—— 模板方法模式
发布日期:2021-05-10 04:59:26 浏览次数:24 分类:精选文章

本文共 2569 字,大约阅读时间需要 8 分钟。

在面向对象程序设计中,程序员常常需要设计一个系统并预先确定算法的关键步骤及其执行顺序。然而,由于具体实现可能与环境相关,这时候模板方法(Template Method)模式便提供了一种灵活的解决方案。

就像银行业务流程中的取号、排队和对银行员工评分一样,这些步骤对每个客户来说都是一样的,可以在父类中实现。而办理具体业务(如存款、取款或转账)则因客户需求而异,适合在子类中延迟实现。这种设计方式很常见,比如人们的日常生活中的起床、吃饭、做事和睡觉,其中“做事”具体行为随时可能改变。

模板方法模式的核心思想是:定义一个操作的算法骨架,并将部分步骤延迟到子类中。具体来说,它是一个类行为型模式,通过在父类中设定一个模板方法,调用包含基本方法的步骤,使子类能够在不改变整体结构的情况下,灵活扩展某些特定步骤。

以下是该模式的主要优点:

  • 封装不变部分,扩展可变部分:将认为是不变部分的算法封装到父类中,实现复用。其余可变部分由子类继承并实现,确保子类能够根据需要展开。

  • 提取公共部分代码:将一个算法的通用部分(如大部分步骤和流程控制)集中定义在父类中,避免重复代码。

  • 符合开闭原则:允许子类通过扩展方式增加功能,而不需要修改父类,从而实现系统设计的开放性和扩展性。

  • 虽然模板方法模式具有诸多优势,但也存在一些缺点:

  • 增加类的复杂性:为每个不同的实现可能要求定义一个新的子类,这会导致类结构变得庞大,影响系统的简洁性和可维护性。

  • 反向控制:父类通过集合调用子类的方法,控制权的流向相对复杂,增加了代码阅读和调试的难度。

  • 扩展的局限性:父类添加新的抽象方法时,所有现有的子类都需要进行相应的修改,这可能导致版本控制和维护困难。

  • 模板方法的结构与实现

    模板方法模式的核心在于抽象类与具体子类之间的协作。它充分利用了多态性技术和反向控制技术,使得父类通过调用基本方法的特定顺序来实现整体功能,而具体每一步的实现则留给子类决定。

    1. 模式的角色

    a. 抽象类(Abstract Class)

    • 模板方法:定义算法的基本流程,通过调用若干基本方法来实现整体功能。

    • 基本方法:可以是以下几种类型:

      • 抽象方法:由子类实现,定义为抽象属性或方法,子类必须在继承时提供具体实现。

      • 具体方法:在抽象类中已经实现,可以通过继承直接使用或重写,没有强制子类实现的要求。

      • 钩子方法:这些方法在抽象类中提供标准实现(如空方法或特定逻辑),并允许子类选择性地重写或扩展。

    b. 具体子类(Concrete Class)

    • 负责实现抽象类中的抽象方法和钩子方法。
    • 提供特定于子类的处理逻辑,使得模板方法的整体功能能够覆盖各种具体需求。

    示例

    // 抽象类 AbstractClass
    public abstract class AbstractClass {
    public void templateMethod() {
    specificMethod();
    abstractMethod1(); // 会被子类实现
    abstractMethod2(); // 会被子类实现
    }
    public void specificMethod() {
    System.out.println("抽类中的具体方法...");
    }
    public abstract void abstractMethod1(); // 抽提出
    public abstract void abstractMethod2(); // 抽提出
    }
    // 具体子类 ConcreteClass
    public class ConcreteClass extends AbstractClass {
    @Override
    public void abstractMethod1() {
    System.out.println("子类实现了 abstractMethod1...");
    }
    @Override
    public void abstractMethod2() {
    System.out.println("子类实现了 abstractMethod2...");
    }
    // 可以添加更多特定的处理逻辑
    public void concreteMethod() {
    System.out.println("子类添加了 concreteMethod...");
    }
    }
    // 测试类
    public class TemplateMethodPattern {
    public static void main(String[] args) {
    AbstractClass obj = new ConcreteClass();
    obj.templateMethod();
    }
    }

    2. 模式的实际应用

    模板方法模式在很多实际应用中都有广泛使用。例如:

    • 配置管理:允许用户自定义模板,灵活配置系统设置。
    • 文档生成:提供标准模板,用户可以根据需要自定义内容。
    • 框架设计:如Spring框架对绑定bean的处理流程,使用模板方法模式提供通用处理,子类可以扩展实现特定绑定逻辑。

    模板方法的优缺点总结

    优点

    • 提供了一种可扩展的设计方式,允许子类灵活扩展。
    • 封装了通用的算法部分,便于复用和维护。
    • 符合开闭原则,便于系统功能的扩展和维护。

    缺点

    • 新增功能可能导致大量的子类迭代更新工作。
    • 可能导致精度控制和调试难度增加。
    • 长期使用可能导致类结构复杂化。

    如何选择适用的场景

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

    • 需要定义一个基本流程,但各具体实现Details可以扩展的场景。
    • 需要提供相同的操作框架,但具体实现Details可以灵活变化。
    • 需要灵活配置不同场景的特定行为。

    这也是什么时候需要使用模板方法的常见理由:当核心流程是固定不变的,但有多个不同的实现方式时。

    如果你的系统架构中有稳定的基础流程,但需要灵活处理不同实现细节,模板方法模式绝对是一个值得考虑的选择。

    上一篇:设计模式(十七)—— 责任链模式
    下一篇:设计模式(十二)—— 享元模式

    发表评论

    最新留言

    感谢大佬
    [***.8.128.20]2025年04月12日 17时12分56秒