1. 程式人生 > 實用技巧 >設計模式之模板方法模式

設計模式之模板方法模式

基本概念

模板方法模式,又叫模板模式。在一個抽象類中公開定義了執行它的方法的模板,它的子類可以按需重寫方法實現,但呼叫將以抽象類中定義的方式進行。

簡單說,模板模式定義了一個操作中的演算法的骨架,而將一些步驟延遲到子類中,使得子類可以不改變一個演算法的結構,就可以重定義該演算法的某些特定步驟。

這種型別的設計模式屬於行為型模式。

模板方法模式的原理類圖

  • AbstractClass,抽象類,類中實現了模板方法,定義了演算法的骨架,具體子類需要去實現。其他的抽象方法有operation2,3,4。
  • ConcreteClass,實現抽象方法operation2,3,4,以完成演算法中特定子類的步驟。

模板方法模式

案例

編寫製作豆漿的程式,說明如下:

  • 製作豆漿的流程:選材—>新增配料—>浸泡—>放到豆漿機打碎。
  • 通過新增不同的配料,可以製作出不同口味的豆漿。
  • 選材、浸泡和放到豆漿機打碎這幾個步驟對於製作每種口味的豆漿都是一樣的。
  • 請使用模板方法模式完成。

思路分析

程式碼實現

 1//抽象類,表示豆漿
2publicabstractclassSoyaMilk{
3
4//模板方法,使用final修飾,不讓子類去覆蓋
5finalvoidmake(){
6select();
7addCondiments();
8soak();
9beat();
10}
11
12//選材料
13void
select()
{
14System.out.println("第一步,選擇好的新鮮黃豆");
15}
16
17//新增不同的配料
18abstractvoidaddCondiments();
19
20//浸泡
21voidsoak(){
22System.out.println("第三步,黃豆和配料開始浸泡");
23}
24
25voidbeat(){
26System.out.println("第四步,黃豆和配料放到豆漿機打碎");
27}
28
29}

1publicclassRedBeanSoyaMilkextendsSoyaMilk{
2@Override
3voidaddCondiments(){
4System.out.println("加入上好的紅豆"
);
5}
6}

1publicclassPeanutSoyMilkextendsSoyaMilk{
2@Override
3voidaddCondiments(){
4System.out.println("加入上好的花生");
5}
6}

 1publicclassClient{
2publicstaticvoidmain(String[]args){
3//製作紅豆豆漿
4SoyaMilkredBeanSoyaMilk=newRedBeanSoyaMilk();
5redBeanSoyaMilk.make();
6//製作花生豆漿
7SoyaMilkpeanutSoyMilk=newPeanutSoyMilk();
8peanutSoyMilk.make();
9}
10}

模板方法模式的鉤子方法

在模板方法模式的父類中,我們可以定義一個方法,它預設不做任何事,子類可以視情況要不要覆蓋它,該方法稱為“鉤子”。

 1//抽象類,表示豆漿
2publicabstractclassSoyaMilk{
3
4//模板方法,使用final修飾,不讓子類去覆蓋
5finalvoidmake(){
6select();
7if(customerWantCondiments()){
8addCondiments();
9}
10soak();
11beat();
12}
13
14//選材料
15voidselect(){
16System.out.println("第一步,選擇好的新鮮黃豆");
17}
18
19//新增不同的配料
20abstractvoidaddCondiments();
21
22//浸泡
23voidsoak(){
24System.out.println("第三步,黃豆和配料開始浸泡");
25}
26
27voidbeat(){
28System.out.println("第四步,黃豆和配料放到豆漿機打碎");
29}
30
31//鉤子方法,決定是否需要新增配料
32booleancustomerWantCondiments(){
33returntrue;
34}
35}

 1publicclassPureSoyaMilkextendsSoyaMilk{
2@Override
3voidaddCondiments(){
4//空實現
5}
6
7@Override
8booleancustomerWantCondiments(){
9returnfalse;
10}
11}

注意事項

基本思想是:演算法只存在於一個地方,也就是在父類中,容易修改。需要修改演算法時,只要修改父類的模板方法或者已經實現的某些步驟,子類就會繼承這些修改。
實現了最大化程式碼複用。父類的模板方法和已實現的某些步驟會被子類繼承而直接使用。

既統一了演算法,也提供了很大的靈活性。父類的模板方法確保了演算法的結構保持不變,同時由子類提供部分步驟的實現。

該模式的不足之處:每一個不同的實現都需要一個子類實現,導致類的個數增加,使得系統更加龐大。

一般模板方法都加上final關鍵字,防止子類重寫模板方法。

模板方法模式使用場景:當要完成在某個過程,該過程要執行一系列步驟,這一系列的步驟基本相同,但其個別步驟在實現時可能不同,通常考慮用模板方法模式來處理。