前言:
如果目前場景遇到一定流程階段,但流程內容依照邏輯或情境不同也有所不一樣. 這時可以考慮使用樣板模式(TemplatePattern)
生活舉例:
因為十二年國教,所以基本上每個人都有上學的經驗
每天上學最少要經歷下面過程(我做一些簡化)
可以看到不管是國小、國中、高中 至少都有上述的過程
但每個過程內容可能會依照年級階段不同,也有所不一樣
例如:
- 吃中餐:高中可能是吃便當,但國小是吃營養午餐,雖然都是吃飯但內容不一樣。
- 上午上課:都是教數學,但高中教微積分,國小教加減乘除。
常見例子:
我們常見的測試框架 MSTest,NUnit.....
都有樣板模式的思想。
一般來說測試框架都有生命週期,只是每個框架命名不一樣但核心原理差不多
- SetUpClass (每個測試類別只都執行一次)
- SetUpUnitTest (每次執行測試方法時都執行一次)
- UnitTest (執行測試方法)
如下圖
(圖片來自網路上)
程式碼範例:
此範例使用Console來模擬單元測試框架流程:
建立一個 UnitFlowBase
抽像類別依照Nunit
生命週期來實現下面方法.
OneTimeSetUp
(每個測試類別只都執行一次)Dispose
(每次執行測試方法時都執行一次)SetUp
每次執行TestCase
前資料初始化TearDown
每次執行TestCase
後釋放資源
此抽象類別提供幾個Hock讓子類實做細節。 UnitFlowBase
只提供框架
UnitTest
對外提供一個void UnitTest(IEnumerable<Func<bool>> testCases)
方法.
可以傳入要驗證動作一個
IEnumerable<Func<bool>>
型別.
1 | public abstract class UnitFlowBase |
建立另一個類別UnitCounter
重載SetUp
,OneTimeSetUp
方法.
1 | public class UnitCounter : UnitFlowBase |
呼叫實我們建立一個UnitCounter
類別,並傳入一個IEnumerable<Func<bool>>
的資料集合
1 | class Program |
實際案例
在我一個開源專案中ElectronicInvoice_TW,有使用到Template Method Pattern
因為在大平台傳送資料有些固定的流程,這個就很適合使用此Pattern.
- 參數需要按照字首排序.
- 參數製作簽章防偽造.
- 利用Http類別請求大平台.
對於每個API來說有一個變化是傳入參數,所以我就把它當作是此系列類別需要override
方法.
而在ApiBase.cs
是所有大平台API的Base
類別在裡面有一個string ExecuteApi(TModel mode)
方法提供給外部呼叫.
詳細資料可自行參閱我的原始碼.
小結:
日後測試程式只需關注我們需要如何實現邏輯細解(重寫三個方法),核心流程順序就交由UnitFlowBase
決定。
__此文作者__:Daniel Shih(石頭)
__此文地址__: https://isdaniel.github.io/template-pattern/
__版權聲明__:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!