C#設計模式之9:模板方法

來源:互聯網
上載者:User

標籤:string   NPU   部分   wan   get   存在   coff   ddc   ring   

模板方法

模板方法是一個方法,定義了演算法的步驟,並允許子類為一個或多個步驟提供實現。

本例中用沖泡咖啡和茶的例子來說明:

說明了沖泡咖啡和茶的步驟,可以看出沖泡咖啡和茶的步驟差不多,很相似,先來看看沒有應用模板方法的代碼:

Tea的代碼類似,就不放了。他們的一個不好的地方在於演算法散落在了各個類中,還有一點是重複的代碼。

public abstract class CaffeineBeverage//設計一個抽象類別,將演算法進行封裝    {        public void BoilWater()        {            Console.WriteLine("boil water");        }        public void PourInCup()        {            Console.WriteLine("pour in cup");        }        public void PrepareRecipe()//封裝演算法,這個就是模板方法。        {            BoilWater();            Brew();            PourInCup();            AddCondiment();        }        public abstract void Brew();//具體的實現要到子類中實現        public abstract void AddCondiment();//具體的實現要到子類中實現    }    public class TeaLogic: CaffeineBeverage    {        public override void Brew()        {            Console.WriteLine("brew tea");        }        public override void AddCondiment()        {            Console.WriteLine("add some lemon");        }    }    public class CoffeLogin:CaffeineBeverage    {        public override void Brew()        {            Console.WriteLine("brew coffe...");        }        public override void AddCondiment()        {            Console.WriteLine("add some milk and sugar...");        }    }

模板方法定義了一個演算法步驟,並允許子類其中一個或多個實現提供步驟。

模板方法的定義:在一個方法中定義演算法的骨架,而將一些步驟延遲到子類中。模板方法可以在子類不改變演算法結構的情況下,重新定義演算法中的某些步驟。

同時,AbstractClass內部定義一個鉤子方法——一個虛方法,可以在子類中決定是否重寫,達到掛鈎的目的。鉤子的存在,可以讓子類有能力對演算法的不同點進行掛鈎,要不要掛鈎,由子類自行決定。

//在模板方法中應用鉤子    public abstract class AnotherKindOfCoffeineBeverage    {        public void BoilWater()        {            Console.WriteLine("boil water");        }        public void PourInCup()        {            Console.WriteLine("pour in cup..");        }        public virtual bool CustomerWantCondiment()//虛方法。。表示一個鉤子        {            return true;        }        public abstract void Brew();        public abstract void AddCondiment();        public void PrepareRecipe()        {            BoilWater();            Brew();            if (CustomerWantCondiment())            {                AddCondiment();            }            PourInCup();        }    }    //應用鉤子方法的一個情境    public class AnotherKindOfTea : AnotherKindOfCoffeineBeverage    {        public override bool CustomerWantCondiment()        {            return GetCustomerInput().Equals("y");        }        public override void Brew()        {            Console.WriteLine("dropping coffe through filter..");        }        public override void AddCondiment()        {            Console.WriteLine("add some condiment..");        }        private string GetCustomerInput()        {            Console.WriteLine("would you like some lemon with your tea?(y/n)");            var input = Console.ReadLine();            return input?.ToLower();        }    }

 

關於鉤子,由這麼一個原則:當你必須提供模板方法中的某個步驟時,就在基類中做成抽象方法,如果這個步驟是可選的,就做成虛方法,鉤子。

鉤子可以讓子類實現演算法中的可選部分,或者在鉤子對於子類的實現不那麼重要的時候,子類可以對此鉤子置之不理。鉤子的另一個用法,是讓子類能夠有機會對模板方法中某些即將發生的步驟做出反應。鉤子也可以讓子類有能力為其抽象類別做一些決定。

最重要的一點:抽象類別中的某些方法是可選的,對於這些可選的方法,就做成鉤子,而不是做成抽象方法,這樣就可以讓子類的負荷減輕。

新的設計原則:好萊塢設計原則——不要調用(打電話給)我們,我會調用(打電話給)你。

 

 

好萊塢原則和模板方法

他們兩個的聯絡還算是比較明顯:當我們設計範本方法時,我們告訴子類,“不要調用我們,我們會調用你”。

好萊塢原則和依賴倒置原則之間的關係:

 

C#設計模式之9:模板方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.