Gof定義
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個 算法的結構即可重定義該算法的某些特定步驟。
動機
在軟件構建過程中,對於某一項任務,它常常有穩定的整體操作結構,但各個子步驟卻有很多改變的需求,或者由於固有的原因(比如框架與應用之間的關係)而無法和任務的整體結構同時實現。如何在確定穩定操作結構的前提下,來靈活應對各個子步驟的變化或者晚期實現需求?
模板方法模式結構圖:
AbstractClass類:這個抽象類中定義了一個模板方法TemplateMethod,該方法通常爲一個具體方法,將抽象類中的一些抽象的操作組合在其中,推遲到子類實現。
ConcreteClass類:按照需求實現父類定義的一個或多個抽象方法。
一個小的例子來反映上面的結構:
/// <summary> /// 測試車的類--->AbstractClass /// </summary> public abstract class Vehical { protected abstract void Start(); //PrimitiveOperation protected abstract void Run(); //PrimitiveOperation protected abstract void Trun(); //PrimitiveOperation protected abstract void Stop(); //PrimitiveOperation /// <summary> /// 相當於TemplateMethod /// </summary> public void Test() { //做記錄等操作 Start(); Run(); Trun(); Stop(); } } /// <summary> /// 紅旗車--->ConcreteClass /// </summary> public class HongQiCar : Vehical { protected override void Start() { Console.WriteLine("測試紅旗車啓動"); } protected override void Run() { Console.WriteLine("測試紅旗車行駛"); } protected override void Trun(int degree) { Console.WriteLine("測試紅旗車轉向"); } protected override void Stop() { Console.WriteLine("測試紅旗車停止"); } } /// <summary> /// QQ車--->ConcreteClass /// </summary> public class QQCar : Vehical { protected override void Start() { Console.WriteLine("測試QQ車啓動"); } protected override void Run() { Console.WriteLine("測試QQ車行駛"); } protected override void Trun(int degree) { Console.WriteLine("測試QQ車轉向"); } protected override void Stop() { Console.WriteLine("測試QQ車停止"); } } /// <summary> /// 客戶代碼 /// </summary> public class App { static void Main() { Vehical vehical; vehical = new HongQiCar(); vehical.Test(); vehical = new QQCar(); vehical.Test(); Console.ReadLine(); } }
Template Method模式的幾個要點
Template Method模式是一種非常基礎性的設計模式,在面向對象系統中有着大量的應用。它用最簡潔的機制(虛函數的多態性)爲很多應用程序框架提供了靈活的擴展點,是代碼複用方面的基本實現結構。
除了可以靈活應對子步驟的變化外,“不要調用我,讓我來調用你”的反向控制結構是Template Method的典型應用。
在具體實現方面,被Template Method調用的虛方法可以具有實現,也可以沒有任何實現(抽象方法、純虛方法),但一般推薦將它們設置爲protected方法。