天天看點

Java設計模式之模闆方法

模闆方法模式定義為:在一個方法中定義了一個算法的骨架或者步驟,而将一些步驟延遲到子類中去實作。模闆方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某一些步驟。

模闆方法在基類中定義了一個操作的流程順序,能夠保證該步驟按序進行,有一些步驟的具體實作在基類中已經聲明,而将一些變化的步驟的具體實作交給了子類去實作,進而就達到了延遲一些步驟到子類中,模闆方法一個最大的好處就是能夠設定一個業務流程能夠按照一定嚴格的順序執行,控制了整個算法的執行步驟。

這個方法将算法定義成一組步驟,其中凡是想讓子類進行自定義實作的步驟,均定義為抽象方法。抽象基類的特點是,一般将模闆方法設定為final,這樣防止子類覆寫該算法的步驟,将一些相同的操作或步驟直接在基類中實作,将一些變化的步驟設定為抽象由子類去完成。

代碼執行個體:

假如要泡杯茶和咖啡,要想泡咖啡則需要先将水煮沸,然後用沸水沖泡咖啡,将咖啡倒進杯子,加糖和牛奶。要想泡茶葉則需要把水煮沸,然後用沸水沖茶葉,将茶倒入杯子,放點檸檬。

通過分析,這些操作基本上都是四步驟,順序都是固定的,且有相同的步驟,則就可以利用模闆方法來将泡飲料的過程制作一個算法的骨架,将變化的部分抽象出來,讓具體的子類去實作。

抽象超類,這個類是負責泡飲料的基類,設定了算法的骨架

package com.whut.modelmethod;

//模闆方法

abstract class BeverageMake {

//final可以防止子類更改覆寫該算法,這樣可以保證算法步驟不被破壞

public final void prepareRecipe()

{

boilWater();

brew();

pourInCup();

addCondiments();

}

abstract void brew();

abstract void addCondiments();

//燒水

publicvoid boilWater()

System.out.println("Now start to boiling water");

//飲料導入杯子彙總

publicvoid pourInCup()

System.out.println("pour the beverage into the cup");

具體的類,茶葉類:

publicclass Tea extends BeverageMake {

@Override

void brew() {

// TODO Auto-generated method stub

System.out.println("boil the tea in the water");

void addCondiments() {

System.out.println("put some condiments into the tea");

測試類:

publicclass MakeTest {

publicstaticvoid main(String[] args) {

Tea tea=new Tea();

tea.prepareRecipe();

模闆方法中挂鈎:

當在模闆方法中某一些步驟是可選的時候,也就是該步驟不一定要執行,可以由子類來決定是否要執行,則此時就需要用上鈎子。鈎子是一種被聲明在抽象類中的方法,但一般來說它隻是空的或者具有預設值,子類可以實作覆寫該鈎子,來設定算法步驟的某一步驟是否要執行。鈎子可以讓子類實作算法中可選的部分,讓子類能夠有機會對模闆方法中某些一即将發生的步驟做出反應。

重寫上面的代碼:

這次茶葉泡好後,加不加東西由子類去決定。

超類:

abstractclass BeverageMake {

if(hookCondiments())

public void boilWater()

public void pourInCup()

//加入了鈎子,來讓子類決定是否執行該步驟

public boolean hookCondiments()

returntrue;

茶葉子類:

//設定不需要加飲料,這樣就可以控制算法的某一個步驟不執行

return false;

設計原則:

别調用我們,我來調用你們。

這種原則主要就是,我們允許底層元件将自己挂鈎到系統上,但是高層元件會決定什麼時候和怎麼樣來使用這些底層元件。

要點:

1)鈎子是一種方法,它在抽象類中不做事,或者是預設的事情,子類可以選擇覆寫它

2)為了防止子類改變模闆方法中的算法骨架,一般将模闆方法聲明為final

3)政策模式和模闆方法都是用于封裝算法,前者是利用組合和委托模型,而後者則是繼承

本文轉自 zhao_xiao_long 51CTO部落格,原文連結:http://blog.51cto.com/computerdragon/1167937