1. 程式人生 > >設計模式——模板方法模式(模板方法模式來寫作文)

設計模式——模板方法模式(模板方法模式來寫作文)

本文首發於cdream的個人部落格,點選獲得更好的閱讀體驗!

歡迎轉載,轉載請註明出處。

本文簡單講述了模板方法模式,例子為如何使作文模板來寫作文。如果想進一步,瞭解模板方法,建議讀完後閱讀一下spring中AbstractApplicationContext類的refresh方法或HttpServelt類中的service方法。

image-20181217201003375

一、概念

定義:模板方法模式(Template method pattern)是一種類的行為設計模式。該模式會在父類的一個操作中定義演算法的結構,然後將具體實現推遲到子類中完成。可以讓子類重新定義某些方法的實現而不改變原來的演算法結構。

當然,父類可以實現該演算法結構的某些方法,將剩餘邏輯交給子類實現,不同的子類有不同的實現。

模板方法模式是最常被使用的設計模式之一,在Servlet裡,記不記的我們要繼承一個HttpServlet類,然後需要重寫doPost()和doGet()方法。還有那個Spring的IoC容器的初始化方法中refresh()就是一個典型的模板方法,這裡面obtainFreshBeanFactory()是抽象方法,postProcessBeanFactory()和onRefresh()是鉤子方法。

二、結構

UML圖:

image-20181217075208695

主要組成部分:

抽象模板類(Template):會定義一個模板方法,模板方法往往是一個具體方法,給出一個固定的方法呼叫順序,其中的抽象方法會推遲到子類中實現。

  1. Template:模板方法,會定義一個邏輯骨架
  2. method01:具體方法,在抽象類中就給出了實現,如果不想讓子類修改,可以給方法加上final
  3. method02:抽象方法,推遲到子類中實現,在不同的子類中可以有不同的實現
  4. 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,這是熟悉設計模式的開發人員的預設做法,以後如果使用鉤子方法時,記得這樣命名,你和其他開發人員就更方便溝通了~

四、優缺點

優點

  • 提高程式碼的複用性,相同的邏輯部分會在抽象類中實現
  • 提高程式碼擴充套件性,將不同部分放入子類,如果需要擴充套件,可以新增新的子類
  • 符合好萊塢原則,由抽象類主控一切,子類絕不直接呼叫抽象類。

缺點

  • 引入了抽象類,每一個不同的實現都需要一個子類來實現,導致類的個數增加,從而增加了系統實現的複雜度。

五、總結

模板方法模式是經常用到的一種設計模式,但也是很容易理解的一種模式。重點在抽象模板類中的模板方法主控一切,需要改變的抽象方法推遲到子類中完成。

值得注意的是,不要與策略模式混淆,策略模式同樣也是封裝演算法,但是策略模式是封裝整個演算法,而模板方法模式是將需要改變的部分在子類中實現;策略方法使用組合,而模板方法是使用繼承。


  1. Head First 設計模式,Eric Freeman &Elisabeth Freeman with Kathy Sierra & Bert Bates
  2. Template method pattern,wiki
  3. 《JAVA與模式》之模板方法模式