著作權聲明:本文由http://leaver.me 翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者部落格連結,謝謝!
介紹
本文實現模板模式
背景
有時候我們需要做很多任務,而做這些任務的演算法可能不同,這樣可以設計成策略模式,這樣。執行該任務的基本的一些代碼就是一樣的。但程式可可以動態切換來執行任務的不同部分了。
現在,真實的情況是有些演算法,從實現層面山看,有可能有一些步驟是不一樣的,這種情況下。我們可以使用繼承來完成。
當有個演算法,而這個演算法的一部分卻多樣的時候。使用模板模式就很好。GoF定義模板模式為:
"Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.".
定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板模式使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
在上面的類圖中:
AbstractClass:包含兩種方法。第一種就是演算法的每一步。另一種就是模板方法。模板方法就是那些可以被用在所有獨立方法中。並且提供了演算法執行的一個骨架
ConcreteClass:這個類重寫了抽象類別中每一步的方法,包含對這些步驟的個人化實現。
使用代碼
看一個簡單的例子。假想我們有一個類用來讀取資料。並且能夠為資訊管理系統到處資料。
abstract class DataExporter{ // 這個方法都是一致的 public void ReadData() { Console.WriteLine("Reading the data from SqlServer"); } // 當報表格式頂的時候這個也是定的。 public void FormatData() { Console.WriteLine("Formating the data as per requriements."); } // 目標檔案類型的不同導致該方法不同 public abstract void ExportData(); // 這是用戶端可能使用的模板方法 public void ExportFormatedData() { this.ReadData(); this.FormatData(); this.ExportData(); }}
ReadData和FormatData 的實現不會變。唯一可變的部分就是ExportData方法。該方法對於不同的匯出類型不同。如果我們要匯出excel檔案。我們要實現一個ConcreteClass的實現。
class ExcelExporter : DataExporter{ public override void ExportData() { Console.WriteLine("Exporting the data to an Excel file."); }}
同樣如果要匯出PDF檔案。重寫這部分即可
class PDFExporter : DataExporter{ public override void ExportData() { Console.WriteLine("Exporting the data to a PDF file."); }}
好處就是用戶端可以使用DataExporter類,而具體的實現是在衍生類別中的
static void Main(string[] args){ DataExporter exporter = null; //匯出 Excel檔案 exporter = new ExcelExporter(); exporter.ExportFormatedData(); Console.WriteLine(); // 匯出 PDF 檔案 exporter = new PDFExporter(); exporter.ExportFormatedData();}
運行時。對演算法的調用將會執行真正請求的衍生類別的方法。
看一下我們的類圖
亮點何在
本文討論了什麼時候模板模式很有用。也簡單的實現了。模板模式是一個典型的好萊塢原則:
別給我們打電話,我們會聯絡你的” 不論什麼時候。模板方法總是在調用衍生類別中的方法。
Demo下載
TemplateMethodDemo.zip
原文地址:Understanding-and-Implementing-Template-Method-Des
著作權聲明:本文由http://leaver.me 翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者部落格連結,謝謝!