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

1. 定義

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

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

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

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

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

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

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

2.2 模式實(shí)現(xiàn)

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

1. 模板方法

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

2. 基本方法

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

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

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

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

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

4. 代碼實(shí)現(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("點(diǎn)單");
    }

    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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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