Java设计模式之模板方法模式Template Method Pattern详解

Java设计模式之模板方法模式Template Method Pattern详解

概述

模板方法模式是一种行为设计模式。在该模式中,有一个抽象类作为模板,其中定义了算法的骨架,具体实现延迟到子类中。这种模式属于行为型模式。

在模板方法模式中,父类定义一个模板方法,该方法作为算法的骨架,而实际的子类实现会覆盖其中的某些步骤,但是整个算法的骨架不会改变。

实现

模板方法模式包含以下角色:

  • 抽象类(Abstract Class):定义一个模板方法和一些抽象方法。
  • 具体类(Concrete Class):实现抽象类中的抽象方法,并覆盖父类中的模板方法中已有的部分逻辑。

抽象类

在抽象类中,定义一个模板方法,该方法中会调用一系列抽象方法。例如:

public abstract class AbstractClass {

   final void templateMethod(){
      firstAbstractOperation();
      secondAbstractOperation();
      thirdAbstractOperation();
   }

   abstract void firstAbstractOperation();
   abstract void secondAbstractOperation();
   abstract void thirdAbstractOperation();    
}

在这个例子中,我们定义了一个抽象类 AbstractClass,其中 templateMethod() 方法是具体算法的骨架。在这个方法中,我们调用了三个抽象方法:firstAbstractOperation()secondAbstractOperation()thirdAbstractOperation()

具体类

在具体类中,我们要实现抽象类中的所有抽象方法,并覆盖父类中的模板方法的已有部分逻辑。例如:

public class ConcreteClass extends AbstractClass {

   void firstAbstractOperation() {
      System.out.println("ConcreteClass firstAbstractOperation");
   }

   void secondAbstractOperation() {
      System.out.println("ConcreteClass secondAbstractOperation");
   }

   void thirdAbstractOperation() {
      System.out.println("ConcreteClass thirdAbstractOperation");       
   }
}

在这个例子中,我们定义了一个具体类 ConcreteClass,并实现了抽象类中的三个抽象方法。这些方法将分别被 templateMethod() 调用。

例子

下面通过两个例子来说明模板方法模式的应用。

例子1:煮咖啡和茶

我们假设有一个咖啡制作过程,又有一个茶制作过程,这两个过程有一些共同的步骤。例如,都需要将水煮沸、将水倒入杯子中等等。

我们可以使用模板方法模式来实现这个例子。首先,我们定义一个抽象类 Beverage,其中 prepareRecipe() 方法是模板方法:

public abstract class Beverage {

    // 模板方法
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }

    abstract void brew();

    abstract void addCondiments();
}

Beverage 类中,我们定义了一个模板方法 prepareRecipe(),在这个方法中,我们定义了几个步骤:boilWater()brew()pourInCup()addCondiments()

接下来,我们定义两个具体类 CoffeeTea,这两个类分别对应咖啡制作和茶制作两个过程:

public class Coffee extends Beverage {

    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
}

public class Tea extends Beverage {

    void brew() {
        System.out.println("Steeping the tea");
    }

    void addCondiments() {
        System.out.println("Adding Lemon");
    }
}

CoffeeTea 类中,我们分别实现了 brew()addCondiments() 两个抽象方法,这些方法将在 prepareRecipe() 中被调用。

现在,我们可以使用这些类来制作咖啡和茶:

Beverage coffee = new Coffee();
coffee.prepareRecipe();

Beverage tea = new Tea();
tea.prepareRecipe();

输出结果如下:

Boiling water
Dripping Coffee through filter
Pouring into cup
Adding Sugar and Milk

Boiling water
Steeping the tea
Pouring into cup
Adding Lemon

从输出结果可以看出,咖啡和茶的制作过程中,都共用了 Beverage 类中定义的一些步骤。

例子2:父母教孩子写作业

我们假设有一个父母教孩子写作业的场景,父母要求孩子按照以下步骤来写作业:

  1. 读懂题目。
  2. 划分大纲。
  3. 编写思维导图。
  4. 撰写正文。
  5. 检查错误并提交。

我们可以使用模板方法模式来实现这个例子。首先,我们定义一个抽象类 Homework,其中 doHomework() 方法是模板方法:

public abstract class Homework {

    // 模板方法
    public final void doHomework() {
        readQuestion();
        makeOutline();
        writeMindMap();
        writeContents();
        checkErrors();
    }

    void readQuestion() {
        System.out.println("Read the homework question");
    }

    void checkErrors() {
        System.out.println("Check errors and submit the homework");
    }

    abstract void makeOutline();

    abstract void writeMindMap();

    abstract void writeContents();
}

Homework 类中,我们定义了一个模板方法 doHomework(),在这个方法中,我们定义了几个步骤:readQuestion()makeOutline()writeMindMap()writeContents()checkErrors()

接下来,我们定义两个具体类 MathHomeworkEnglishHomework,这两个类分别对应数学作业和英语作业:

public class MathHomework extends Homework {

    void makeOutline() {
        System.out.println("Make an outline of the math homework");
    }

    void writeMindMap() {
        System.out.println("Write a mind map for the math homework");
    }

    void writeContents() {
        System.out.println("Write the contents of the math homework");
    }
}

public class EnglishHomework extends Homework {

    void makeOutline() {
        System.out.println("Make an outline of the English homework");
    }

    void writeMindMap() {
        System.out.println("Write a mind map for the English homework");
    }

    void writeContents() {
        System.out.println("Write the contents of the English homework");
    }
}

MathHomeworkEnglishHomework 类中,我们分别实现了 makeOutline()writeMindMap()writeContents() 三个抽象方法,这些方法将在 doHomework() 中被调用。

现在,我们可以使用这些类来教孩子写作业:

Homework mathHomework = new MathHomework();
mathHomework.doHomework();

Homework englishHomework = new EnglishHomework();
englishHomework.doHomework();

输出结果如下:

Read the homework question
Make an outline of the math homework
Write a mind map for the math homework
Write the contents of the math homework
Check errors and submit the homework

Read the homework question
Make an outline of the English homework
Write a mind map for the English homework
Write the contents of the English homework
Check errors and submit the homework

从输出结果可以看出,父母教孩子写数学作业和英语作业过程中,都共用了 Homework 类中定义的一些步骤。

总结

模板方法模式是一种常用的设计模式,它可以将具体实现延迟到子类中,从而使算法的骨架不会改变。在实际应用中,我们可以根据具体的场景,使用这种模式来提高代码的复用性和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之模板方法模式Template Method Pattern详解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • java 中的封装介绍及使用方法

    Java中的封装介绍及使用方法 封装是面向对象思想中的三大特性之一,它指的是将一个对象的属性和方法组合成一个有机的整体,并尽可能地隐藏内部细节,从而实现对外提供接口,使得对象更加安全、稳定和易于使用。 在Java中,封装通常建立在以下几个关键字上:public、private、protected以及default(缺省)。 public关键字 public关…

    other 2023年6月25日
    00
  • uml14种图记忆口诀

    以下是关于“UML 14种图记忆口诀”的完整攻略: UML是一种用于软件开发的标准建模语言,包括14种不同类型的图。为了更好地记忆这些,可以使用以下口诀: 序图:时间轴,垂直画。 用例图:用户需求,功能列。 类图:属性和方法,关系连。 活动图:流程控制,节点画。 状态图:状态变化,箭头连。 部署图:物理结构,节点画。 组件图:模块划分,节点画。 对象图:实例…

    other 2023年5月7日
    00
  • Android自定义WheelView地区选择三级联动

    一、背景介绍 在开发Android应用时,通过使用WheelView控件,我们可以实现像省市区选择器、时间选择器等功能。本文着重介绍如何使用自定义的WheelView控件实现地区选择三级联动的功能。 二、自定义WheelView控件 为了实现三级联动的地区选择功能,我们需要先自定义一个可以支持多级数据的控件。这里我们借鉴开源控件library中的WheelV…

    other 2023年6月25日
    00
  • 让自解压文件在右键中不显示的实现方法

    让我来详细讲解“让自解压文件在右键菜单中不显示”的实现方法。 介绍 自解压文件通常指的是带有解压自身所需程序的可执行文件,使用时只需双击即可自动解压,非常方便。不过,在右键菜单中出现自解压文件会显得有些多余,尤其是对于某些需要隐私保护的文件时更为重要,因此禁止其出现可使文件更安全。 实现方法 实现自解压文件在右键菜单中不显示的方法,我们需要做两件事情: 修改…

    other 2023年6月27日
    00
  • Win11 Canary Build 25387.1200预览版今日发布: 主要用于测试服务管道

    Win11 Canary Build 25387.1200预览版攻略 Win11 Canary Build 25387.1200是Windows 11操作系统的预览版之一,旨在测试服务管道的功能和稳定性。本攻略将详细介绍如何安装和使用该预览版,并提供两个示例说明。 步骤1:准备工作 在开始之前,请确保你已经满足以下要求: 一台兼容的计算机,满足Windows…

    other 2023年8月3日
    00
  • 制作简单的wpf时钟

    以下是制作简单的WPF时钟的完整攻略: WPF时钟的基本原理 WPF时钟是一个基于WPF(Windows Presentation Foundation)的应用程序,它使用系统时间来显示当前时间。WPF时钟的基本原理是使用WPF的动画功能来实现时钟的指针移动。 制作WPF时钟的步骤 以下是制作WPF时钟的基本步骤: 创建一个新的WPF应用程序。 在XAML文…

    other 2023年5月6日
    00
  • 电脑如何查看上次重启时间? windows查看上一次开机时间的三种方法

    下面是电脑如何查看上次重启时间以及Windows查看上一次开机时间的三种方法的攻略: 1. 使用命令行方式查看上次重启时间 使用命令行方式是最为实用和便捷的查看电脑上次重启时间的方法,该方法适用于所有Windows系统。具体操作步骤如下: 步骤1: 打开命令行窗口。点击开始菜单,输入“CMD”或者“命令行”等关键字,选择“命令提示符”打开。 步骤2: 输入命…

    other 2023年6月26日
    00
  • C++使用模板实现单链表

    这里是C++使用模板实现单链表的攻略: 第一步:定义节点类 单链表的每个节点都包含两个部分,一个是数据部分,一个是指向下一个节点的指针。因此我们需要先定义一个节点类,代码如下: template <class T> class Node{ public: Node<T>* next; T data; Node(); Node(cons…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部