設計模式——模板方法模式(模板方法模式來寫作文)
本文首發於cdream的個人部落格,點選獲得更好的閱讀體驗!
歡迎轉載,轉載請註明出處。
本文簡單講述了模板方法模式,例子為如何使作文模板來寫作文。如果想進一步,瞭解模板方法,建議讀完後閱讀一下spring中AbstractApplicationContext類的refresh方法或HttpServelt類中的service方法。
一、概念
定義:模板方法模式(Template method pattern)是一種類的行為設計模式。該模式會在父類的一個操作中定義演算法的結構,然後將具體實現推遲到子類中完成。可以讓子類重新定義某些方法的實現而不改變原來的演算法結構。
當然,父類可以實現該演算法結構的某些方法,將剩餘邏輯交給子類實現,不同的子類有不同的實現。
模板方法模式是最常被使用的設計模式之一,在Servlet裡,記不記的我們要繼承一個HttpServlet類,然後需要重寫doPost()和doGet()方法。還有那個Spring的IoC容器的初始化方法中refresh()就是一個典型的模板方法,這裡面obtainFreshBeanFactory()是抽象方法,postProcessBeanFactory()和onRefresh()是鉤子方法。
二、結構
UML圖:
主要組成部分:
抽象模板類(Template):會定義一個模板方法,模板方法往往是一個具體方法,給出一個固定的方法呼叫順序,其中的抽象方法會推遲到子類中實現。
- Template:模板方法,會定義一個邏輯骨架
- method01:具體方法,在抽象類中就給出了實現,如果不想讓子類修改,可以給方法加上final
- method02:抽象方法,推遲到子類中實現,在不同的子類中可以有不同的實現
- hook:鉤子方法,抽象類給出了預設實現,子類也可以根據需要對該方法進行重寫
抽象類實現(SubClass):模板類中的抽象方法會在子類中實現,不同的子類中演算法會有不同的實現,其中SubClass2選擇了重寫hook方法,而SubClass1選擇了抽象類中預設實現。
三、誰又沒背過幾篇作文模板呢?
都是應試教育過來的人,想必大家都背過幾個作文模板吧~哈哈,接下來,我們就用模板方法模式做一個簡單的作文模板!
這是個作文模板,也就是模板方法模式裡面的抽象類,start和end都是鉤子方法,content是抽象方法,需要推遲到子類中實現
public abstract class CompositionTemplate {
public void template(){
start();
content();
end();
}
public void start(){
System.out.println("As far as I am concerned,");
}
public void end(){
System.out.println("In a word,");
}
public abstract void content();
}
一篇關於保護環境的文章
public class Composition1 extends CompositionTemplate {
@Override
public void content() {
System.out.println("李華認為保護環境很重要!");
}
}
一篇關於經濟的文章
public class Composition2 extends CompositionTemplate {
@Override
public void content() {
System.out.println("小白認為經濟發展更重要!");
}
}
搞起來~
public class Test {
public static void main(String[] args) {
CompositionTemplate composition1 = new Composition1();
CompositionTemplate composition2 = new Composition2();
composition1.template();
System.out.println("--------------");
composition2.template();
}
}
------>
As far as I am concerned,
李華認為保護環境很重要!
In a word,
--------------
As far as I am concerned,
小白認為經濟發展更重要!
In a word,
看有了模板之後,我們只需要在不同的文章裡將中間的content部分重寫就可以了,如果同學姿勢水平比較高,那就連開頭結尾的兩個鉤子方法也重寫了,哈哈~
我自己寫這個模板方法,不要太簡單,大家如果感興趣,我強烈建議看一下HttpServlet裡面的service方法,這是一個很經典模板方法模式,裡面的doPost、doGet、doDelete等等,都是鉤子方法,在抽象類裡有預設實現,在子類中可以重寫。
另外,值得注意的是,鉤子方法的命名規則是doXXX,這是熟悉設計模式的開發人員的預設做法,以後如果使用鉤子方法時,記得這樣命名,你和其他開發人員就更方便溝通了~
四、優缺點
優點
- 提高程式碼的複用性,相同的邏輯部分會在抽象類中實現
- 提高程式碼擴充套件性,將不同部分放入子類,如果需要擴充套件,可以新增新的子類
- 符合好萊塢原則,由抽象類主控一切,子類絕不直接呼叫抽象類。
缺點
- 引入了抽象類,每一個不同的實現都需要一個子類來實現,導致類的個數增加,從而增加了系統實現的複雜度。
五、總結
模板方法模式是經常用到的一種設計模式,但也是很容易理解的一種模式。重點在抽象模板類中的模板方法主控一切,需要改變的抽象方法推遲到子類中完成。
值得注意的是,不要與策略模式混淆,策略模式同樣也是封裝演算法,但是策略模式是封裝整個演算法,而模板方法模式是將需要改變的部分在子類中實現;策略方法使用組合,而模板方法是使用繼承。