標籤: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:模板方法