23種設計模式之模板方法模式(Template Method Pattern)
基本概念
模板方法模式是一種行為型設計模式,它定義了一個算法骨架,將某些算法步驟的實現延遲到子類中。
這樣可以使得算法的框架不被修改,但是具體的實現可以根據需要進行調整。
結構組成
在模板方法模式中,我們通常會定義一個抽象類,它包含了一個模板方法和一些抽象方法,這些抽象方法通常由子類來實現。
- 定義抽象類(Abstract Class):抽象類中定義了一些抽象方法和一個模板方法。抽象方法通常是一些具體步驟,而模板方法則定義了算法的大致流程。由于抽象類中的某些方法需要由子類來實現,因此它們往往是 protected 訪問權限。
- 定義具體子類(Concrete Class):具體子類繼承自抽象類,并實現其中的抽象方法。在具體子類中,我們可以針對需要實現的具體步驟編寫相應的代碼。
(1)小栗子
假設我們需要 實現一個炒菜的步驟,炒菜的步驟是固定的,分為倒油、熱油、倒蔬菜、倒調料品、翻炒等步驟。現通過模板方法模式來用代碼模擬。
抽象類
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 炒包菜
/*** 炒包菜*/
public class FryDaBaiCai extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("放入大白菜");}@Overridepublic void pourSauce() {System.out.println("放入辣椒");}
}
具體子類2 炒空心菜
/*** 炒空心菜*/
public class FryKxc extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("放入空心菜");}@Overridepublic void pourSauce() {System.out.println("放入大蒜");}
}
測試
public class FryTest {public static void main(String[] args) {FryDaBaiCai fryDaBaiCai = new FryDaBaiCai();fryDaBaiCai.cookProcess();FryKxc fryKxc = new FryKxc();fryKxc.cookProcess();}
}
輸出結果:
倒油
熱油
放入大白菜
放入辣椒
翻炒至熟
--------------------------------
倒油
熱油
放入空心菜
放入大蒜
翻炒至熟
(2)小栗子
假設我們要實現一個對一個數組進行排序的程序,我們可以定義一個抽象類 ArraySorter,其中包含一個模板方法 sort,
這個方法包含以下步驟:檢查數組是否為空、確定排序算法、調用具體的排序算法。
我們可以將其中一步 “調用具體的排序算法” 延遲到子類中具體實現。在具體子類中,我們可以實現具體的排序算法,如快排、冒泡排序、插入排序等。
抽象類
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-冒泡排序
public class BubbleSorter extends ArraySorter {@Overrideprotected void selectAlgorithm() {System.out.println("Bubble sorting algorithm selected.");}@Overrideprotected void sortArray(int[] array) {// 具體的冒泡排序算法實現}
}
具體子類2-快速排序
public class QuickSorter extends ArraySorter {@Overrideprotected void selectAlgorithm() {System.out.println("Quick sorting algorithm selected.");}@Overrideprotected void sortArray(int[] array) {// 具體的快排算法實現}
}
測試
我們定義了一個抽象類 ArraySorter,其中包含一個模板方法 sort。在具體子類中,我們分別實現了 BubbleSorter 和 QuickSorter,重寫了父類的 selectAlgorithm 和 sortArray 方法。
當需要對數組進行排序時,只需要創建一個具體的子類,并調用 sort 方法即可。例如:
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);}
}