天天看點

模闆方法模式 模闆方法模式

标簽 : Java與設計模式

模闆方法模式: 定義一個操作中的算法的骨架, 而将一些步驟延遲到子類中. 模闆方法使得子類可以在不改變一個算法的結構的前提下重定義該算法的某些特定步驟.

Tips

處理某個流程的骨架代碼已經具備, 但其中某節點的具體實作暫不确定, 此時可采用模闆方法, 将該節點的代碼實作轉移給子類完成. 即: 處理步驟在父類中定義好, 具體實作延遲到子類中定義.

到ATM取款機辦理業務, 都會經過插卡、輸密碼、處理業務、取卡 等幾個過程, 而且這幾個過程一定是順序執行的, 且除了 處理業務 (如取款、改密、查賬) 可能會有所不同之外, 其他的過程完全相同. 是以我們就可以參考模闆方法模式把插卡、輸密碼、取卡 3個過程放到父類中實作, 并定義一個流程骨架, 然後将 處理業務的具體邏輯 放到子類中:

AbstractClass 抽象模闆:

定義抽象的原語操作,具體的子類将重定義它們以實作一個算法的各步驟.

實作一個模闆方法,定義一個算法的骨架. 該模闆方法不僅調用原語操作,也調用定義在AbstractClass或其他對象中的操作.

<code>AbstractATMBusiness</code>是一個模闆方法, 它定義了ATM操作的一個主要步驟并确定他們的先後順序, 但允許子類改變這些具體步驟以滿足各自的需求.

ConcreteClass

實作原語操作以完成算法中與特定子類相關的步驟; 每個AbstractClass都可有任意多個ConcreteClass, 而每個ConcreteClass都可以給出這些抽象方法的不同實作, 進而使得頂級邏輯的功能各不相同:

Client

<code>HttpServlet</code>定義了<code>service()</code>方法固定下來HTTP請求的整體處理流程,使得開發Servlet隻需繼承<code>HttpServlet</code>并實作<code>doGet()</code>/<code>doPost()</code>等方法完成業務邏輯處理, 并不需要關心具體的HTTP響應流程:

将這個示例放在此處可能有些不大合适, 但它也展現了一些模闆方法的思想:

ScheduleTaskMonitor

ScheduleTask

隻需在Spring的配置檔案中引入該Bean:

需要統一定時的類實作<code>ScheduleTask</code>接口, 并将自己注冊到<code>monitor</code>中:

即可完成<code>scheduleTask()</code>方法的定時排程.

模闆方法模式提供了一個很好的代碼複用平台, 他通過把不變行為搬移到父類, 去除子類中重複代碼來展現它的優勢: 有時我們會遇到由一系列步驟構成的過程需要執行, 該過程從高層次上看是相同的, 但有某些細節的實作可能不同, 此時就可以考慮使用用模闆方法了.

适用

一次性實作算法的不變部分, 并将可變的行為留給子類來實作;

各子類中公共的行為應該被提取出來并集中到一個公共父類中避免代碼重複, 如: Servlet 的 <code>service()</code>方法.

控制子類擴充, 模闆方法隻在特定點調用hook操作, 這樣就隻允許在這些點進行擴充, 如: Junit測試架構.

相關模式

Factory Method常被模闆方法調用.

Strategy: 模闆方法使用繼承來改變算法的一部分, Strategy使用委托來改變整個算法.

<dl></dl>

<dt>參考 &amp; 擴充</dt>