一、理論基礎
1.在現實中我們經常會遇到這種情況,有些事情的實現有固定的流程步驟,但是每一個步驟的具體實現是可變的,如我們申請護照的步驟一般是提交申請、提交相關材料、窗口辦理、銀行繳費、領證,這是一個固定不變的流程,但是對於每一個步驟具體怎樣實現對於每一個辦理點來說可能不一樣,如領證這個步驟,我可以是直接去辦理點領取,也可以是選擇郵寄等;
2.以上這類問題應用到軟件領域,我們可以採用模板方法模式來進行設計;
3.模板方法模式:定義一個操作中算法的框架,而將一些步驟延遲到子類,他使得子類可以不改變一個算法的機構就可以重新定義該算法的某些步驟;
4.在模板方法模式中我們將實現功能的每一個步驟所對應的方法稱爲基本方法,調用這些基本方法同時定義這些基本方法執行順序的方法稱爲模板方法;
5.通過使用模板方法模式,可以將一些複雜流程的實現步驟封裝在一系列基本方法中,在抽象父類中提供一個稱之爲模板方法的方法來定義這些基本方法的執行次序,而通過其子類來覆蓋某些步驟,從而使得相同的算法框架可以有不同的執行結果;
二、實例
1.首先定義一個抽象基類,在該類中定義了一個模板方法,該方法決定了算法的總體框架和各個步驟的執行順序
namespace TemplateMethod
{
/// <summary>
/// 抽象基類,在基類中定義算法骨架即模板方法和基本方法
/// 1.模板方法是具體方法,因此不能用接口來實現模板方法模式;
/// 2.模板方法定義了總體框架即決定了總體業務流程順序,不能被子類修改;
/// 3.基本方法可以是抽象方法、具體方法、虛方法等;
/// </summary>
public abstract class AbstractBase
{
/// <summary>
/// 模板方法,定義算法骨架
/// 如:以請客吃飯爲例,總得骨架爲怎麼到目的地、吃什麼、點單、買單、怎麼回家
/// 其中點單和買單可能都是一樣的,所以我們可以再父類中實現
/// </summary>
public void TemplateMethod()
{
ToDestination();
ToEat();
SinglePoint();
Pay();
GoHome();
}
/// <summary>
/// 去目的地
/// </summary>
public abstract void ToDestination();
/// <summary>
/// 吃東西
/// </summary>
public abstract void ToEat();
/// <summary>
/// 回家
/// </summary>
public abstract void GoHome();
/// <summary>
/// 點單
/// </summary>
public void SinglePoint()
{
Console.WriteLine("叫服務員點單");
}
/// <summary>
/// 買單
/// </summary>
public void Pay()
{
Console.WriteLine("到服務檯買單");
}
}
}
2.定義子類繼承抽象基類,同時根據不同的需求實現基類中特定的抽象方法
namespace TemplateMethod
{
/// <summary>
/// 學生類
/// </summary>
public class Student:AbstractBase
{
public override void ToDestination()
{
Console.WriteLine("我是學生,我坐公交去目的地");
}
public override void ToEat()
{
Console.WriteLine("我是學生,我吃漢堡");
}
public override void GoHome()
{
Console.WriteLine("我是學生,我坐公交回學校");
}
}
}
namespace TemplateMethod
{
/// <summary>
/// 工作的人
/// </summary>
public class WorkMen:AbstractBase
{
public override void ToDestination()
{
Console.WriteLine("我在上班,我開車去目的地");
}
public override void ToEat()
{
Console.WriteLine("我要吃佛跳牆");
}
public override void GoHome()
{
Console.WriteLine("我開車回家");
}
}
}
3.使用者根據特定的需求進行調用
namespace TemplateMethod
{
public class Program
{
public static void Main(string[] args)
{
AbstractBase pStudent = new Student();
pStudent.TemplateMethod();
Console.WriteLine("***********************************");
AbstractBase pWorkMen = new WorkMen();
pWorkMen.TemplateMethod();
Console.ReadLine();
}
}
}
三、實質
1.抽象共同點:對業務或算法中相同的邏輯框架進行抽象;
2.封裝變化點:將框架中各個步驟的具體實現進行封裝;
3.主要形式:定義一個抽象基類,在抽象基類中定義一個模板方法,該方法決定算法中各個步驟的執行順序;定義子類繼承與該抽象基類,並實現該抽象基類中的各個步驟,流程的控制由父類進行控制。
四、使用場景
1.某個方法的實現需要多個步驟,其中某些步驟的實現是固定的,某些步驟的實現是變化的;
2.我們知道一個業務或算法所需的關鍵步驟,並確定了這些步驟的執行順序,但某些步驟的具體實現是未知的,或者說某些步驟的實現與具體的環境有關;