C#設計模式-模板方法模式(Template Method)

概念

模板指一些能夠套用的公共內容,例如網頁模板是當網站中有許多頁面版式色彩相同的狀況下,將其定義爲網頁模板,並定義其中部分可編輯,部分不可編輯,那麼在利用網頁模板製做其餘頁面時就會很方便,不易出錯。
在設計模式中,模板方法模式中模板和生活中模板概念很是相似,在一個抽象類中定義一個操做中的算法骨架(對應於模板),而將一些步驟延遲到子類中去實現(對應根據本身的狀況向模板填充內容)。
在面向對象程序設計過程當中,程序員經常會遇到這種狀況:設計一個系統時知道了算法所需的關鍵步驟,並且肯定了這些步驟的執行順序,但某些步驟的具體實現還未知,或者說某些步驟的實現與具體的環境相關。此時就能夠採用模板方法進行設計。程序員

例如公司的入職流程,進入公司,入職準備、入職報到、辦理入職手續、進行入職培訓,轉正,入職結束進入崗位。這些步驟都很固定,可是不一樣的公司,流程中每一個步驟稍有不一樣。這些不一樣的能夠在具體實現上進行填充。算法

特色

優勢:
它封裝了不變部分,擴展可變部分。它把認爲是不變部分的算法封裝到父類中實現,而把可變部分算法由子類繼承實現,便於子類繼續擴展。
它在父類中提取了公共的部分代碼,實現了代碼複用。
部分方法是由子類實現的,所以子類能夠經過擴展方式增長相應的功能,符合開閉原則。設計模式

缺點:
對每一個不一樣的實現都須要定義一個子類,這會致使類的個數增長,系統更加龐大,設計也更加抽象。
父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這致使一種反向的控制結構,它提升了代碼閱讀的難度。
由於引入了一個抽象類,若是具體實現過多的話,須要用戶或開發人員須要花更多的時間去理清類之間的關係。ide

模式結構

根據模板方法模式類圖結構,有利於咱們理清該模式中類之間的關係,具體類圖以下:網站

模板方法模式中涉及的角色:
抽象模板角色:定義了一個或多個抽象操做,以便讓子類實現,這些抽象操做稱爲基本操做。它由一個模板方法和若干個基本方法構成。
  模板方法:定義了算法的骨架,按某種順序調用其包含的基本方法。
  基本方法:是整個算法中的一個步驟,包含了抽象方法、具體方法。
具體模板角色:實現父類所定義的一個或多個抽象方法。this

應用場景

算法的總體步驟很固定,但其中個別部分易變時,這時候可使用模板方法模式,將容易變的部分抽象出來,供子類實現。
當多個子類存在公共的行爲時,能夠將其提取出來並集中到一個公共父類中以免代碼重複。首先,要識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。lua

實現

以入職流程爲例,進行具體的實現。spa

using System;

namespace 模板模式
{
    class EntryProcess
    {
        static void Main(string[] args)
        {
            SamsungEntryProcess samsung = new SamsungEntryProcess();
            HuaweiEntryProcess huawei = new HuaweiEntryProcess();

            samsung.JoiningCompany();
            huawei.JoiningCompany();

            Console.Read();
        }
    }

    // 抽象類,入職流程
    public abstract class TemplateEntryProcess
    {
        // 模板方法,不要把模版方法定義爲 Virtual 或 abstract 方法,避免被子類重寫,防止更改流程的執行順序
        public void JoiningCompany()
        {
            this.entryCompany(); // 進入公司
            this.preparationForEntry(); // 入職前準備,整理衣帽等
            this.registrationForEmployment(); // 入職報到
            this.entryProcedures(); // 辦理入職手續
            this.inductionTraining(); // 入職培訓
            this.evaluationOfConversion(); // 轉正評估
            this.entryOver(); // 入職結束,進入崗位
        }

        public abstract void entryCompany();

        public void preparationForEntry()
        {
            Console.WriteLine("作準備,整理衣帽等;");
        }

        public void registrationForEmployment()
        {
            Console.WriteLine("入職報到;");
        }
        public void entryProcedures()
        {
            Console.WriteLine("辦理入職手續;");
        }
        public void inductionTraining()
        {
            Console.WriteLine("進行入職培訓;");
        }
        public void evaluationOfConversion()
        {
            Console.WriteLine("完成入職前培訓,進行轉正評估;");
        }
        public void entryOver()
        {
            Console.WriteLine("入職流程完成,進入崗位。");
        }

    }

    // 具體子類,三星入職
    public class SamsungEntryProcess: TemplateEntryProcess
    {
        public override void entryCompany()
        {
            Console.WriteLine("進入三星公司");
        }

    }

    // 具體子類,華爲入職
    public class HuaweiEntryProcess: TemplateEntryProcess
    {
        public override void entryCompany()
        {
            Console.WriteLine("進入華爲公司");
        }
    }
}

執行後結果設計

進入三星公司
作準備,整理衣帽等;
入職報到;
辦理入職手續;
進行入職培訓;
完成入職前培訓,進行轉正評估;
入職流程完成,進入崗位。
進入華爲公司
作準備,整理衣帽等;
入職報到;
辦理入職手續;
進行入職培訓;
完成入職前培訓,進行轉正評估;
入職流程完成,進入崗位。
相關文章
相關標籤/搜索