【设计模式】模板方法模式(Template Method Pattern)

23种设计模式之模板方法模式(Template Method Pattern)

基本概念

模板方法模式是一种行为型设计模式,它定义了一个算法骨架,将某些算法步骤的实现延迟到子类中。

这样可以使得算法的框架不被修改,但是具体的实现可以根据需要进行调整。

结构组成

在模板方法模式中,我们通常会定义一个抽象类 ,它包含了一个模板方法 和一些抽象方法 ,这些抽象方法通常由子类来实现。

  • 定义抽象类(Abstract Class):抽象类中定义了一些抽象方法和一个模板方法。抽象方法通常是一些具体步骤,而模板方法则定义了算法的大致流程。由于抽象类中的某些方法需要由子类来实现,因此它们往往是 protected 访问权限。
  • 定义具体子类(Concrete Class):具体子类继承自抽象类,并实现其中的抽象方法。在具体子类中,我们可以针对需要实现的具体步骤编写相应的代码。

(1)小栗子

假设我们需要 实现一个炒菜的步骤,炒菜的步骤是固定的,分为倒油、热油、倒蔬菜、倒调料品、翻炒等步骤。现通过模板方法模式来用代码模拟。

抽象类

java 复制代码
public abstract class AbstractClass {

    /**
     * 定义唯一一个模板方法,定义了基本方法的执行流程,因为执行流程是固定的不应该被修改,所以使用final修饰
     */
    public final void cookProcess() {
        pourOil();
        heatOil();
        pourVegetable();
        pourSauce();
        fry();
    }

    /**
     * 第一步,倒油
     */
    public void pourOil() {
        System.out.println("倒油");
    }

    /**
     * 第二步,热油,直接实现该方法
     */
    public void heatOil() {
        System.out.println("热油");
    }

    /**
     * 第三步,倒素菜,这是不一样的,一个是下包菜,一个是下空心菜,
     * 需要用户自己实现,抽象方法
     */
    public abstract void pourVegetable();

    /**
     * 第四步,倒调味料,这也是不一样的,抽象方法
     */
    public abstract void pourSauce();

    /**
     * 第五步,翻炒
     */
    public void fry() {
        System.out.println("翻炒至熟");
    }
}

具体子类1 炒包菜

java 复制代码
/**
 * 炒包菜
 */
public class FryDaBaiCai extends AbstractClass{

    @Override
    public void pourVegetable() {
        System.out.println("放入大白菜");
    }

    @Override
    public void pourSauce() {
        System.out.println("放入辣椒");
    }
}

具体子类2 炒空心菜

java 复制代码
/**
 * 炒空心菜
 */
public class FryKxc extends AbstractClass{

    @Override
    public void pourVegetable() {
        System.out.println("放入空心菜");
    }

    @Override
    public void pourSauce() {
        System.out.println("放入大蒜");
    }
}

测试

java 复制代码
public class FryTest {
    
    public static void main(String[] args) {
        FryDaBaiCai fryDaBaiCai = new FryDaBaiCai();
        fryDaBaiCai.cookProcess();
        
        FryKxc fryKxc = new FryKxc();
        fryKxc.cookProcess();
    }
}

输出结果:

shell 复制代码
倒油
热油
放入大白菜
放入辣椒
翻炒至熟
--------------------------------
倒油
热油
放入空心菜
放入大蒜
翻炒至熟    

(2)小栗子

假设我们要实现一个对一个数组进行排序的程序,我们可以定义一个抽象类 ArraySorter ,其中包含一个模板方法 sort ,

这个方法包含以下步骤:检查数组是否为空、确定排序算法、调用具体的排序算法。

我们可以将其中一步 "调用具体的排序算法" 延迟到子类中具体实现。在具体子类中,我们可以实现具体的排序算法,如快排、冒泡排序、插入排序等。

抽象类

java 复制代码
public abstract class ArraySorter {

    public final void sort(int[] array) {
        if (array == null || array.length == 0) {
            return;
        }
        selectAlgorithm();
        sortArray(array);
    }

    protected abstract void selectAlgorithm();

    protected abstract void sortArray(int[] array);
}

具体子类1-冒泡排序

java 复制代码
public class BubbleSorter extends ArraySorter {
    @Override
    protected void selectAlgorithm() {
        System.out.println("Bubble sorting algorithm selected.");
    }

    @Override
    protected void sortArray(int[] array) {
        // 具体的冒泡排序算法实现
    }
}

具体子类2-快速排序

java 复制代码
public class QuickSorter extends ArraySorter {
    @Override
    protected void selectAlgorithm() {
        System.out.println("Quick sorting algorithm selected.");
    }

    @Override
    protected void sortArray(int[] array) {
        // 具体的快排算法实现
    }
}

测试

我们定义了一个抽象类 ArraySorter,其中包含一个模板方法 sort。在具体子类中,我们分别实现了 BubbleSorter 和 QuickSorter,重写了父类的 selectAlgorithm 和 sortArray 方法。

当需要对数组进行排序时,只需要创建一个具体的子类,并调用 sort 方法即可。例如:

java 复制代码
public class TestSelectSort {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7};
        ArraySorter sorter = new BubbleSorter();
        sorter.sort(array);
    }
}
相关推荐
凤凰院凶涛QAQ1 小时前
《Java版数据结构 & 集合类剖析》Map & Set & 反射:“从哈希碰撞到红黑树转换,反射帮你扒开 HashMap 的桶数组看个究竟”
java·数据结构·算法
H.莓飛1 小时前
【数据结构】排序_OJ题(一):计数、桶与排序后的处理
java·开发语言·数据结构
wangchunyu1142 小时前
JAVA AQS与Lock实现原理(含CAS)
java·开发语言·word
w_zero_one3 小时前
算法--模拟
java·数据结构·算法
Javatutouhouduan3 小时前
阿里1658页Java面试题总结(含答案)
java·高并发·java面试·java面试题·后端开发·java程序员·java八股文
秋天的怀念_David3 小时前
算法一千零一夜 · 第十三夜 幻方,武侠世界里的数学迷宫
java·程序人生·算法
专业程序开发源4 小时前
springboot欧缇蔓月子中心管理系统82697-计算机课程设计、毕业设计
java·spring boot·后端·python·spring·django·课程设计
秋天的怀念_David4 小时前
算法一千零一夜 · 第十四夜 幻方与奇妙的二进制
java·程序人生·算法
thefool1122664 小时前
网络编程^
java
Thinker QAQ5 小时前
并发编程(十一):Shared Memory 与 Message Passing——关系与组合使用
java·python·go·并发编程·shared memory·message passing