(七)設(shè)計模式之模板方法模式

1. 定義

模板方法模式:定義一個操作中算法的框架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

Template Method Pattern:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

模板方法模式是一種基于繼承的代碼復(fù)用技術(shù),它是一種類行為型模式。

模板方法模式是結(jié)構(gòu)最簡單的行為型設(shè)計模式,在其結(jié)構(gòu)中只存在父類與子類之間的繼承關(guān)系。通過使用模板方法模式,可以將一些復(fù)雜流程的實現(xiàn)步驟封裝在一系列基本方法中,在抽象父類中提供一個稱之為模板方法的方法來定義這些基本方法的執(zhí)行次序,而通過其子類來覆蓋某些步驟,從而使得相同的算法框架可以有不同的執(zhí)行結(jié)果。模板方法模式提供了一個模板方法來定義算法框架,而某些具體步驟的實現(xiàn)可以在其子類中完成。

2. 模板方法模式結(jié)構(gòu)與實現(xiàn)

2.1 模式結(jié)構(gòu)

模板方法模式結(jié)構(gòu)比較簡單,其核心是抽象類和其中的模板方法的設(shè)計,其結(jié)構(gòu)如圖所示:

由圖可知,模板方法模式包含如下兩個角色:

(1) AbstractClass(抽象類):在抽象類中定義了一系列基本操作(PrimitiveOperations),這些基本操作可以是具體的,也可以是抽象的,每一個基本操作對應(yīng)算法的一個步驟,在其子類中可以重定義或?qū)崿F(xiàn)這些步驟。同時,在抽象類中實現(xiàn)了一個模板方法(Template Method),用于定義一個算法的框架,模板方法不僅可以調(diào)用在抽象類中實現(xiàn)的基本方法,也可以調(diào)用在抽象類的子類中實現(xiàn)的基本方法,還可以調(diào)用其他對象中的方法。

(2) ConcreteClass(具體子類):它是抽象類的子類,用于實現(xiàn)在父類中聲明的抽象基本操作以完成子類特定算法的步驟,也可以覆蓋在父類中已經(jīng)實現(xiàn)的具體基本操作。

2.2 模式實現(xiàn)

在實現(xiàn)模板方法模式時,開發(fā)抽象類的軟件設(shè)計師和開發(fā)具體子類的軟件設(shè)計師之間可以進行協(xié)作。一個設(shè)計師負責(zé)給出一個算法的輪廓和框架,另一些設(shè)計師則負責(zé)給出這個算法的各個邏輯步驟。實現(xiàn)這些具體邏輯步驟的方法即為基本方法,而將這些基本方法匯總起來的方法即為模板方法,模板方法模式的名字也因此而來。下面將詳細介紹模板方法和基本方法:

1. 模板方法

一個模板方法是定義在抽象類中的、把基本操作方法組合在一起形成一個總算法或一個總行為的方法。這個模板方法定義在抽象類中,并由子類不加以修改地完全繼承下來。模板方法是一個具體方法,它給出了一個頂層邏輯框架,而邏輯的組成步驟在抽象類中可以是具體方法,也可以是抽象方法。由于模板方法是具體方法,因此模板方法模式中的抽象層只能是抽象類,而不是接口。

2. 基本方法

基本方法是實現(xiàn)算法各個步驟的方法,是模板方法的組成部分?;痉椒ㄓ挚梢苑譃槿N:抽象方法(Abstract Method)、具體方法(Concrete Method)和鉤子方法(Hook Method)。

(1)抽象方法:一個抽象方法由抽象類聲明、由其具體子類實現(xiàn)。在C#語言里一個抽象方法以abstract關(guān)鍵字標識。

(2)具體方法:一個具體方法由一個抽象類或具體類聲明并實現(xiàn),其子類可以進行覆蓋也可以直接繼承。

(3)鉤子方法:一個鉤子方法由一個抽象類或具體類聲明并實現(xiàn),而其子類可能會加以擴展。通常在父類中給出的實現(xiàn)是一個空實現(xiàn)(可使用virtual關(guān)鍵字將其定義為虛函數(shù)),并以該空實現(xiàn)作為方法的默認實現(xiàn),當然鉤子方法也可以提供一個非空的默認實現(xiàn)。

3. 結(jié)構(gòu)實例

4. 代碼實現(xiàn)

using UnityEngine;

public class DM04TempleMethod:MonoBehaviour
{
    void Start()
    {
        IPeople people=new NorthPeople();
        people.Eat();
    }
}

public abstract class IPeople
{
    public void Eat()
    {
        OrderFoods();
        EatSomething();
        PayBill();
    }

    private void OrderFoods()
    {
        Debug.Log("點單");
    }

    protected virtual void EatSomething()
    {
        
    }

    private void PayBill()
    {
        Debug.Log("買單");
    }
}

public class NorthPeople : IPeople
{
    protected override void EatSomething()
    {
        Debug.Log("我在吃面條");
    }
}

public class SouthPeople : IPeople
{
    protected override void EatSomething()
    {
        Debug.Log("我在吃米飯");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容