Template Method模式
在面向物件系統的分析與設計過程中經常會遇到這樣一種情況:對於某一個業務邏輯(演算法實現)在不同的物件中有不同的細節實現,但是邏輯(演算法)的框架(或通用的應用演算法)是相同的。Template Method提供了這種情況的一個實現框架。
Template Method模式是採用繼承的方式實現這一點:將邏輯(演算法)框架放在抽象基類中,並定義好細節的介面,子類中實現細節。
Strategy模式解決的是和Template Method模式類似的問題,但是Strategy模式是將邏輯(演算法)封裝到一個類中,並採取組合(委託)的方式解決這個問題。
解決這個問題可以採取兩種模式來解決,一是
圖2-1:Template模式結構圖
Template Method模式實際上就是利用面向物件中多型的概念實現演算法實現細節和高層介面的鬆耦合。可以看到Template Method模式採取的是繼承方式實現這一點的,由於繼承是一種強約束性的條件,因此也給Template Method模式帶來一些許多不方便的地方。
/// Benchmark
///</summary>
publicabstract
{
publicvoid TemplateMethod()
{
this.Primitive1();
this.Primitive2();
}
protectedabstractvoid Primitive1();
protectedabstractvoid Primitive2();
}
publicclass ConcreteClass1 : AbstractClass
{
public ConcreteClass1()
}
protectedoverridevoid Primitive1()
{
Console.WriteLine("ConcreteClass1µÄOperation1");
}
protectedoverridevoid Primitive2()
{
Console.WriteLine("ConcreteClass1µÄOperation2");
}
}
publicclass ConcreteClass2 : AbstractClass
{
public ConcreteClass2()
{
}
protectedoverridevoid Primitive1()
{
Console.WriteLine("ConcreteClass2µÄOperation1");
}
protectedoverridevoid Primitive2()
{
Console.WriteLine("ConcreteClass2µÄOperation2");
}
}
///<summary>
/// Class1
///</summary>
class Class1
{
///<summary>
///
///</summary>
[STAThread]
staticvoid Main(string[] args)
{
//
// TODO:
//
AbstractClass tmp1 =new ConcreteClass1();
tmp1.TemplateMethod();
tmp1 =new ConcreteClass2();
tmp1.TemplateMethod();
Console.Read();
}
}
Template Method模式的實現關鍵是將通用演算法(邏輯)封裝起來,而將演算法細節讓子類實現(多型)。唯一注意的是我們將原語操作(細節演算法)定義為受保護(Protected)成員,對外部只提供模板方法供呼叫。
Template模式是很簡單模式,但是也應用很廣的模式。Template Method是採用繼承的方式實現演算法的異構,其關鍵點就是將通用演算法封裝在抽象基類中,並將不同的演算法細節放到子類中實現。
Template Method模式獲得一種反向控制結構效果,這也是面向物件系統的分析和設計中一個原則----DIP(依賴倒置:Dependency Inversion Principles)。其含義就是父類呼叫子類的操作(高層模組呼叫低層模組的操作),低層模組實現高層模組宣告的介面。這樣控制權在父類(高層模組),低層模組反而要依賴高層模組。
繼承的強制性約束關係也讓Template Method模式有不足的地方,我們可以看到對於各個ConcreteClass類中的實現的原語方法Primitive (),是不能被別的類複用的。假設我們要建立一個AbstractClass的變體AnotherAbstractClass,並且兩者只是通用演算法不一樣,其原語操作想複用AbstractClass的子類的實現。但是這是不可能實現的,因為ConcreteClass繼承自AbstractClass,也就繼承了AbstractClass的通用演算法,AnotherAbstractClass是複用不了ConcreteClass的實現,因為後者不是繼承自前者。
Template Method模式暴露的問題也正是繼承所固有的問題,Strategy模式則通過組合(委託)來達到和Template Method模式類似的效果,其代價就是空間和時間上的代價。