1. 模板方法模式
1.1 定義
模板方法模式,定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重新定義該算法的某些特定步驟。(引自《大話設計模式》)
1.2 基本結構圖
1.3 模式理解
從類圖中可看出,該模式的核心就是繼承。
舉個栗子,可以更加直觀的理解。比如說,現在有學生a、學生b,現在學習製作蛋糕,製作蛋糕的步驟大致爲:
(1)製作蛋糕坯
(2)製作奶油
(3)diy造型
可以看出,步驟(1)(2)爲學生a和學生b都需要做的相同的操作,即重複性操作,而步驟(3)爲各自不同的操作,即特定步驟。
所以,我們可以將重複性操作(1)(2)提煉出來,放在父類,而將不同的特定操作(3)放在各自的子類去實現。
2. 實戰應用
就採用上面的例子了。下面上代碼~
父類
package main.mode.mbffms2;
public abstract class CakeSuper {
public void makeCake() {
System.out.println("蛋糕坯做好了!");
}
public void makeCream() {
System.out.println("奶油做好了!");
}
public abstract void diy();
}
子類-學生a
package main.mode.mbffms2;
public class StudentA extends CakeSuper{
@Override
public void diy() {
System.out.println("diy一個小熊圖案。");
}
}
子類-學生b
package main.mode.mbffms2;
public class StudentB extends CakeSuper{
@Override
public void diy() {
System.out.println("diy一個大獅子!");
}
}
測試類
package main.mode.mbffms2;
public class Test {
public static void main(String[] args) {
CakeSuper student1 = new StudentA();
System.out.println("學生a做的蛋糕");
student1.makeCake();
student1.makeCream();
student1.diy();
System.out.println("-------華麗麗的分割線-------");
CakeSuper student2 = new StudentB();
System.out.println("學生b做的蛋糕");
student2.makeCake();
student2.makeCream();
student2.diy();
}
}
結果:
啦啦啦,這樣一個模板方法的例子就寫好了!從代碼也可以看出子類的代碼很簡單,只需要實現有差異的步驟(3)的實現,而將重複的步驟(1)(2)放在父類裏面。
3. 總結
3.1 使用場景
當我們要完成在某一細節層次一致的一個過程或一系列步驟,但其個別步驟在更詳細的層次上的實現可能不同時,就可以考慮使用模板方法模式。
3.2 一些說明
(1)模板方法定義了算法的步驟,將重複性步驟留在了父類,有差異的特殊步驟延遲到了子類實現。
(2)不變的行爲放在超類,去除了子類重複性代碼,增強了複用性。(這主要體現了繼承的特點)
(3)當不變和可變的行爲混合在子類中,並且不變行爲會重複出現時,通過模板方法模式將不變行爲提取到超類中,這樣可以大大簡化子類的代碼,減少贅餘。
(4)模板方法的抽象類可以定義抽象方法、具體方法和鉤子方法。
簡單解釋下這三類方法:
抽象方法:抽象類聲明,具體實現由子類完成。如上面的方法diy()。
具體方法:抽象類聲明並實現,子類不做實現和覆蓋。如上面的方法makeCake()和方法makeCream()。
鉤子方法:抽象類聲明並實現,子類會做一些擴展。通常情況下,抽象類會給出一個空方法,作爲默認實現方法。上面的例子裏沒有體現。
(5)提到算法,想到了之前整理過的策略模式。策略模式和模板方法模式相同點在於都封裝了算法,不同在於策略模式的算法在於組合,模板方法模式的算法在於繼承。
說在後面:
本文主要是小貓看《大話設計模式》的筆記式的記錄,其中,也閱讀了許多其它博友的博文,整理出此文,方便以後查閱。