模板方法模式

模板方法模式

含義概述

模板方法模式在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。

使用場景

當(dāng)有一個業(yè)務(wù)有 N 個步驟( 模板 ),其中一部分步驟是永恒不變的,那么就將不變的這些步驟抽象到父類中,可能變化的步驟留給子類去實現(xiàn)。

組成元素

  • 模板方法:定義算法的整體流程,通常推薦使用 final 關(guān)鍵字修飾,防止子類重寫,從而破壞了模板中規(guī)定好的流程
  • 抽象方法:使用 abstract 修飾,讓子類去實現(xiàn)
  • 普通方法:父類提供默認(rèn)實現(xiàn),設(shè)置為private則不允許子類也可重寫,設(shè)置為public或者proteced則允許子類重寫,具體訪問修飾符的級別設(shè)置可以根據(jù)需求設(shè)定,不做強(qiáng)制規(guī)定
  • 鉤子方法:模板方法中提前預(yù)埋多個鉤子,讓子類有一定的能力影響抽象類中的算法流程。

案例

  1. Servlet 中的模板方法:doGet()/doPost()/service()方法
  2. Arrays.sort() 方法,它要求對象實現(xiàn) Comparable 接口

優(yōu)缺點比較

模板方法模式是將子類中不變的部分抽象到父類,可變的部分由子類去實現(xiàn)。

  1. 優(yōu)點
    封裝不變公共代碼,便于維護(hù)??勺儾糠值拇a由子類自由決定,擴(kuò)展性強(qiáng)。

  2. 缺點
    每新增一個不同的實現(xiàn)都需要增加一個子類,可能導(dǎo)致類數(shù)量變多,增加系統(tǒng)復(fù)雜性。

實例

Cook.java

public abstract class Cook {

    /**
     * 鉤子的開關(guān)變量
     */
    protected boolean needBeforeCook = false;

    /**
     * 鉤子的開關(guān)
     *
     * @return
     */
    protected boolean needBeforeCook() {
        System.out.println("===鉤子函數(shù)被禁用===");
        return false;
    }

    /**
     * 鉤子函數(shù)
     */
    public void beforeCook() {
    }


    public void open() {
        System.out.println("打開抽油煙機(jī)");
    }

    public void fire() {
        System.out.println("生火");
    }

    /**
     * 期望子類去實現(xiàn)
     */
    public abstract void doCook();

    public void outfire() {
        System.out.println("滅火");
    }

    public void close() {
        System.out.println("關(guān)閉抽油煙機(jī)");
        System.out.println("======收工=======");
    }

    /**
     * 使用final關(guān)鍵字,防止子類重寫
     */
    public final void cook() {
        // 默認(rèn)開啟鉤子函數(shù)
        if (this.needBeforeCook()) {
            this.beforeCook();
        }

        this.open();
        this.fire();
        this.doCook();
        this.outfire();
        this.close();
    }
}

CookMeat.java

/**
 * 炒肉
 */
public class CookMeat extends Cook {

    @Override
    public boolean needBeforeCook() {
        return true;
    }

    @Override
    public void beforeCook() {
        System.out.println("腌制");
    }

    @Override
    public void doCook() {
        System.out.println("紅燒肉");
    }
}

CookVegatables.java

public class CookVegatables extends Cook {


    @Override
    public void doCook() {
        System.out.println("炒蔬菜");
    }
}

單元測試

import com.netease.learn.designPattern.templateMethod.Cook;
import com.netease.learn.designPattern.templateMethod.CookMeat;
import com.netease.learn.designPattern.templateMethod.CookVegatables;
import org.junit.Test;

public class TemplateMethodTest {

    @Test
    public void test1() {
        Cook cook = new CookMeat();
        cook.cook();
    }

    @Test
    public void test2() {
        Cook cook = new CookVegatables();
        cook.cook();
    }
}

參考資料

  1. 代碼倉庫-模板方法模式
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容