動機:在軟件構建過程當中,對於某一項任務,他經常有穩定的總體操做結構,但各個子步驟卻有不少改變的需求,或者因爲固有的緣由(好比框架與應用之間的關係)而沒法和任務的總體結構同時實現;如何在肯定穩定操做結構的前提下,來靈活應對各類子步驟的變化或者晚期實現需求?算法
意圖:定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod是的子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。框架
適用性:ide
一、一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。測試
二、各子類中公共的行爲應被提取出來並集中到一個公共父類中以免代碼重複。這是O p d y k e 和J o h n s o n 所描述過的「重分解以通常化」的一個很好的例子[ O J 9 3 ]。首先識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。spa
三、控制子類擴展。模板方法只在特定點調用「h o o k 」操做,這樣就只容許在這些點進行擴展。設計
UML圖解:code
示例:假設要開發一款汽車測試程序,而對於測試什麼類型和什麼牌子的汽車,都是是未知的。應用模板方法來設計,咱們就能夠先把汽車測試程序測試涉及的方法列舉出來,對於某些測試方法具體實現留給後來汽車廠商去實現,代碼以下blog
汽車測試軟件框架部分:開發
1 //汽車測試軟件框架的開發組——先開發 2 namespace TemplateMethod 3 { 4 public abstract class Vehicle 5 { 6 protected abstract void Startup(); 7 protected abstract void Run(); 8 protected abstract void Turn(); 9 protected abstract void Stop(); 10 11 public void Test() 12 { 13 Startup();//晚綁定,留給應用程序開發人員實現,擴展點 14 //測試數據記錄... 15 16 Run();//晚綁定,留給應用程序開發人員實現,擴展點 17 //測試數據記錄... 18 19 Turn();//晚綁定,留給應用程序開發人員實現,擴展點 20 //測試數據記錄... 21 22 Stop();//晚綁定,留給應用程序開發人員實現,擴展點 23 //測試數據記錄... 24 } 25 } 26 27 public class VehicleTestFramework 28 { 29 public static void DoTest(Vehicle vehicle) 30 { 31 //... 32 vehicle.Test(); 33 //... 34 } 35 } 36 }
具體汽車廠商後來實現部分:event
1 //具體汽車廠商汽車測試程序程序開發組——晚開發 2 namespace TemplateMethod 3 { 4 public class DaZhongCar:Vehicle 5 { 6 protected override void Startup() 7 { 8 //... 9 } 10 11 protected override void Run() 12 { 13 //... 14 } 15 16 protected override void Turn() 17 { 18 //... 19 } 20 21 protected override void Stop() 22 { 23 //... 24 } 25 } 26 }