定義:模板方法模式在一個(gè)方法中定義一個(gè)算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。模板方法就是一個(gè)固定步驟的“算法”骨架方法。這個(gè)算法的可變部分通過(guò)繼承,在子類中重載實(shí)現(xiàn)。這樣就可以在算法骨架不變的情況下,算法細(xì)節(jié)步驟根據(jù)不同的需求進(jìn)行適應(yīng)的改變,類圖如下:
優(yōu)點(diǎn):
● 模板方法模式在定義了一組算法,將具體的實(shí)現(xiàn)交由子類負(fù)責(zé)。
● 模板方法模式是一種代碼復(fù)用的基本技術(shù)。
● 模板方法模式導(dǎo)致一種反向的控制結(jié)構(gòu),通過(guò)一個(gè)父類調(diào)用其子類的操作,通過(guò)對(duì)子類的擴(kuò)展增加新的行為,符合“開(kāi)閉原則”。
缺點(diǎn):
● 每一個(gè)不同的實(shí)現(xiàn)都需要一個(gè)子類來(lái)實(shí)現(xiàn),導(dǎo)致類的個(gè)數(shù)增加,是的系統(tǒng)更加龐大。
使用場(chǎng)景:
● 一次性實(shí)現(xiàn)一個(gè)算法的不變的部分,并將可變的行為留給子類來(lái)實(shí)現(xiàn)。
● 各子類中公共的行為應(yīng)被提取出來(lái)并集中到一個(gè)公共父類中以避免代碼重復(fù)。
● 控制子類的擴(kuò)展。
案例1:泡茶,泡咖啡有好多共同步驟,如下:
● 煮沸水
● 加入茶葉沖泡(咖啡粉)
● 根據(jù)需求加入調(diào)料(如蜂蜜、檸檬,糖)
● 將泡好的茶水倒入杯子
泡茶代碼如下(咖啡也類似,所以省略了哦):
public class Tea {
// 執(zhí)行步驟
void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() { System.out.println("Boiling water");}
public void steepTeaBag() {System.out.println("Steeping the tea"); }
public void addLemon() { System.out.println("Adding Lemon"); }
public void pourInCup() { System.out.println("Pouring into cup");}
}
我們不難發(fā)現(xiàn)這兩個(gè)類中代碼重復(fù)了很多,步驟一樣,我們可以封裝起來(lái),我們用模板方法模式來(lái)修改,如下:
模板方法代碼:
public abstract class CaffeineBeverage {
final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
}
泡茶代碼:
public class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("Steeping the tea");
}
public void addCondiments() {
System.out.println("Adding Lemon");
}
}
總結(jié):子類可以靈活實(shí)現(xiàn)每個(gè)步驟的具體邏輯,執(zhí)行步驟用抽象類里的prepareRecipe()方法決定。
案例2:鉤子的使用,鉤子就是一個(gè)boolean狀態(tài),控制prepareRecipe()里是否需要執(zhí)行某個(gè)步驟代碼(子類自行修改),如下:
public abstract class CaffeineBeverageWithHook {
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
abstract void brew();
abstract void addCondiments();
void boilWater() { System.out.println("Boiling water");}
void pourInCup() { System.out.println("Pouring into cup"); }
// 鉤子方法
boolean customerWantsCondiments() {
return true;
}
}
Java中的模板方法模式:
● Applet
● Swing里的JFrame
● java.io.InputStream, java.io.OutputStream, java.io.Reader 以及 java.io.Writer 中所有非抽象方法。
● java.util.AbstractList, java.util.AbstractSet 以及 java.util.AbstractMap中所有非抽象方法。
設(shè)計(jì)原則:好菜鳥(niǎo)原則,不要找我們,我們會(huì)找你的。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。