天天看點

設計模式-模闆模式(Template Pattern)

推薦:​​Java設計模式彙總​​

模闆模式

定義

定義一個操作中的算法的骨架,而将一些步驟延遲到子類中。模闆方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

類型

行為型。

例子

舉慕課網的例子,當講師釋出新課程時,慕課網一般要求講師制作PPT、制作視訊、編寫手記(可選)、打包課程等,是以我們可以将這一過程模闆化,可選的操作這裡使用鈎子方法(也可以在抽象類中不出現,由子類來添加實作即可),不可選或者說必須的操作就直接​​

​final​

​​,即不可重寫。

ACourse類(課程抽象類),定義了講師釋出新課程時的一些操作。

package com.kaven.design.pattern.behavioral.templatemethod;

public abstract class ACourse {
    protected  final void makeCourse(){
        this.makePPT();
        this.makeVideo();
        if(needWriteArticle()){
            this.writeArticle();
        }
        this.packageCourse();
    }

    final void makePPT(){
        System.out.println("制作PPT");
    }
    final void makeVideo(){
        System.out.println("制作視訊");
    }
    final void writeArticle(){
        System.out.println("編寫手記");
    }
    //鈎子方法
    protected boolean needWriteArticle(){
        return false;
    }
    abstract void packageCourse();
}      

DesignPatternCourse類(設計模式課程類),繼承了ACourse類,實作了自己的打包課程方法​

​packageCourse()​

​​ ,并且需要編寫手記,使用鈎子方法改變預設行為​

​needWriteArticle()​

​。

package com.kaven.design.pattern.behavioral.templatemethod;

public class DesignPatternCourse extends ACourse {
    void packageCourse() {
        System.out.println("提供課程Java源代碼");
    }

    @Override
    protected boolean needWriteArticle() {
        //需要編寫手記
        return true;
    }
}      

FECourse類(前端課程),繼承了ACourse類,實作了自己的打包課程方法​

​packageCourse()​

​ ,并且不需要編寫手記(ACourse類中預設行為)。

package com.kaven.design.pattern.behavioral.templatemethod;

public class FECourse extends ACourse {
    void packageCourse() {
        System.out.println("提供課程的前端代碼");
        System.out.println("提供課程的圖檔等多媒體素材");
    }
}      

應用層代碼:

package com.kaven.design.pattern.behavioral.templatemethod;

public class Test {
    public static void main(String[] args) {
        System.out.println("後端設計模式課程start——");
        ACourse designPatternCourse = new DesignPatternCourse();
        designPatternCourse.makeCourse();
        System.out.println("後端設計模式課程end——");

        System.out.println("前端課程start——");
        ACourse fePatternCourse = new FECourse();
        fePatternCourse.makeCourse();
        System.out.println("前端課程end——");
    }
}      

輸出:

後端設計模式課程start——
制作PPT
制作視訊
編寫手記
提供課程Java源代碼
後端設計模式課程end——
前端課程start——
制作PPT
制作視訊
提供課程的前端代碼
提供課程的圖檔等多媒體素材
前端課程end——      

從上面的代碼例子中,我們可以發現,在定義父類的模闆方法的時候,我們将模闆方法增加了final修飾,這樣做的目的是為了子類對于父類的擴充原則是應該不修改父類原有的基本方法,模闆方法在定義上面就是來定義整個架構的,​

​而這個設計也符合設計模式中的“開閉原則”-對擴充開放,對修改關閉​

​,可選的方法,就可以使用鈎子方法。

這裡便完成了一個簡單的模闆模式例子。

應用場景

  • 多個産品有相同或者類似的場景。

優點

  • 具體細節步驟實作定義在子類中,子類定義詳細處理算法是不會改變算法整體結構。
  • 存在一種反向的控制結構,通過父類調用其子類的操作,通過子類對父類進行擴充增加新的行為,符合“開閉原則”。
  • 提取公共代碼,便于維護。
  • 每個不同的實作都需要定義一個子類,會導緻類的個數增加,系統更加龐大。

繼續閱讀