軟體設計模式系列之二十四——模板方法模式

cooldream2009發表於2023-10-05

在軟體設計領域,設計模式是一組被反覆使用、多次實踐驗證的經典問題解決方案。其中,模板方法模式是一種行為型設計模式,用於定義一個演算法的骨架,將演算法中的某些步驟延遲到子類中實現,從而使子類可以重新定義演算法的某些特定步驟,同時保持演算法的整體結構不變。本文將深入探討模板方法模式,包括其定義、舉例、結構、實現步驟、程式碼實現、典型應用場景、優缺點、類似模式以及一個小結。

1 模式的定義

模板方法模式是一種行為型設計模式,它定義了一個演算法的骨架,將演算法的具體步驟延遲到子類中實現。這意味著,模板方法模式允許多個子類共享相同的演算法框架,但可以在子類中實現各自特定的步驟,從而實現了程式碼的複用和擴充套件。通常,模板方法由一個抽象類定義,其中包含了演算法的骨架,以及一些抽象方法,用於由子類來實現。

2 舉例說明

在日常生活中,有許多例子符合模板方法模式的設計,這些例子都展示了一種在不同場景中重複使用相同的步驟或演算法骨架的情況。以下是幾個大家熟知的例子:

烹飪食物:烹飪是一個典型的模板方法模式示例。無論是製作披薩、漢堡、還是義大利麵,都需要執行一系列共同的步驟,如準備食材、烹飪、裝盤等。不同的食物有不同的特定步驟,可以在子類中實現。

咖啡店的飲料製作:就像前文提到的咖啡和茶的例子一樣,咖啡店製作不同飲料也遵循相似的模板,包括燒水、沖泡、倒入杯子和加入調味品等步驟。

電子商務購物流程:線上購物網站通常具有相似的購物流程,包括瀏覽商品、將商品新增到購物車、填寫配送資訊、選擇支付方式、確認訂單等步驟。不同電子商務網站可以在這些步驟的執行順序和細節上進行定製。

這些例子都展示了在日常生活中廣泛存在的模板方法模式的應用,其中共享的步驟或演算法骨架可以在不同的情境中重複使用,而特定的細節可以在子類或具體例項中定製。這種設計方法有助於提高效率、減少重複工作,並確保一致性。

3 結構

模板方法模式包含以下主要組成部分:

抽象類(Abstract Class):定義演算法的骨架,包含一個或多個抽象方法,用於由子類實現。通常,抽象類還包含模板方法,該方法定義了演算法的步驟順序。

具體子類(Concrete Subclass):實現抽象類中的抽象方法,從而提供了演算法的具體實現。

4 實現步驟

下面是使用模板方法模式的一般實現步驟:

建立一個抽象類,定義演算法的骨架,並在其中宣告抽象方法。

在抽象類中實現模板方法,該方法包含演算法的步驟順序,其中呼叫了抽象方法。

建立具體子類,繼承自抽象類,並實現抽象方法以提供具體的演算法實現。

在客戶端程式碼中,使用具體子類來呼叫模板方法以執行演算法。

5 程式碼實現

以下是一個使用Java語言實現的製作咖啡和茶的示例程式碼:

// 抽象類:飲料製備模板
abstract class Beverage {
    // 模板方法,製備飲料
    final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // 抽象方法:燒水
    abstract void boilWater();

    // 抽象方法:沖泡
    abstract void brew();

    // 抽象方法:倒入杯子
    abstract void pourInCup();

    // 抽象方法:加入調味品
    abstract void addCondiments();
}

// 具體子類:咖啡
class Coffee extends Beverage {
    @Override
    void boilWater() {
        System.out.println("燒水");
    }

    @Override
    void brew() {
        System.out.println("沖泡咖啡");
    }

    @Override
    void pourInCup() {
        System.out.println("倒入杯子");
    }

    @Override
    void addCondiments() {
        System.out.println("加入糖和牛奶");
    }
}

// 具體子類:茶
class Tea extends Beverage {
    @Override
    void boilWater() {
        System.out.println("燒水");
    }

    @Override
    void brew() {
        System.out.println("沖泡茶葉");
    }

    @Override
    void pourInCup() {
        System.out.println("倒入杯子");
    }

    @Override
    void addCondiments() {
        System.out.println("加入檸檬");
    }
}

public class TemplateMethodPatternExample {
    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        coffee.prepareBeverage();

        Beverage tea = new Tea();
        tea.prepareBeverage();
    }
}

6 典型應用場景

模板方法模式在實際軟體開發中有許多應用場景,其中一些典型的包括:

框架設計:在框架中,模板方法模式用於定義框架的核心演算法,而具體的功能由子類實現。例如,Java中的Servlet就是使用了模板方法模式。

庫設計:在庫中,模板方法模式用於定義通用的演算法,以滿足不同的客戶需求。客戶可以透過繼承庫中的類並實現抽象方法來自定義功能。

遊戲開發:在遊戲開發中,模板方法模式可用於定義遊戲中的角色行為或關卡設計,其中不同的角色或關卡可以透過繼承來實現特定的行為。

7 優缺點

優點:

程式碼複用:模板方法模式提供了一種程式碼複用的方式,使得多個子類可以共享演算法的核心結構,減少了重複程式碼的數量。

擴充套件性:模板方法模式允許子類擴充套件或修改演算法的特定步驟,而不需要改變演算法的整體結構。

高層控制:模板方法模式將演算法的控制權交給了抽象類,使得高層模組可以更方便地控制演算法的執行。

缺點:

過度抽象:如果不合理地設計抽象類和抽象方法,可能會導致過度抽象,使得程式碼難以理解和維護。

限制子類:模板方法模式要求子類必須按照模板方法的順序執行演算法步驟,這可能會限制子類的靈活性。

8 類似模式

與模板方法模式類似的模式包括以下幾種:

策略模式(Strategy Pattern):策略模式也允許在執行時選擇演算法,但與模板方法模式不同,它將演算法封裝成獨立的物件,使得客戶可以在執行時切換不同的演算法實現。模板方法模式透過繼承來實現演算法的變化,而策略模式透過組合和委託來實現。兩者都涉及到將演算法進行抽象,但模板方法模式更適用於定義演算法的骨架,而策略模式更適用於在不同演算法之間進行動態切換。

工廠方法模式(Factory Method Pattern):工廠方法模式用於建立物件,它定義一個建立物件的介面,但讓子類決定例項化哪個類。雖然工廠方法模式通常不涉及演算法的執行順序,但它也可以看作是一種建立物件的模板,具有一定的相似性。兩者都涉及建立物件,但工廠方法模式關注物件的建立,而模板方法模式關注定義演算法的骨架。

命令模式(Command Pattern):命令模式將請求封裝成物件,使得可以在不同的上下文中執行請求。雖然命令模式主要關注將請求和執行解耦,但在一些情況下,可以使用模板方法模式來定義具體的命令執行流程。兩者都涉及定義執行流程,但命令模式主要用於將請求和執行解耦,而模板方法模式主要用於定義演算法的骨架。

雖然這些模式有一些相似之處,但它們的主要關注點和使用方式略有不同。模板方法模式的主要目的是定義演算法的骨架,允許子類定製特定的步驟,而其他模式更側重於其他領域,如建立物件、封裝請求等。因此,在選擇使用哪種模式時,需要根據具體的需求和問題來決定哪種模式更適合。

9 小結

模板方法模式是一種強大的設計模式,它允許我們定義演算法的骨架並延遲特定步驟的實現到子類中。透過這種方式,我們可以實現程式碼的複用和擴充套件,同時保持演算法的整體結構不變。在實際應用中,模板方法模式常用於框架和庫的設計,以及需要定義多個具有相似結構的演算法的場景。但要謹慎使用,避免過度抽象和限制子類的問題。在正確的情況下,模板方法模式可以提高程式碼的可維護性和靈活性,使軟體更易於擴充套件和維護。

相關文章