1. 程式人生 > >設計模式-模板方法(Template Method)

設計模式-模板方法(Template Method)

概述

  • 定義 : 定義了一個演算法的骨架, 並允許子類為一個或多個步驟提供實現
  • 模板方法使得子類可以在不改變演算法結構的情況下, 重新定義演算法的某些步驟
  • 型別 : 行為型

適用場景

  • 一次性實現一個演算法的不變的部分, 並將可變的行為留給子類來實現
  • 各子類中公共的行為被提取出來並集中到一個公共的父類中, 從而避免程式碼重複

優點

  • 提供複用性
  • 提高擴充套件性
  • 符合開閉原則

缺點

  • 類數目增加
  • 增加了系統實現的複雜度
  • 繼承關係自身缺點, 如果父類新增新的抽象方法, 那麼所有子類都要修改

擴充套件

  • 鉤子方法

模式角色

  • AbstractClass(抽象類) :

    • 定義抽象的原語操作(primitive operation),具體的子類將重定義它們以實現一個演算法的各步驟。
    • 實現一個模板方法,定義一個演算法的骨架。該模板方法不僅呼叫原語操作,也呼叫定義
      在AbstractClass或其他物件中的操作。
  • ConcreteClass(具體類) : 實現原語操作以完成演算法中與特定子類相關的步驟

程式碼實現

場景

將一件東西放入冰箱, 需要如下步驟:

  1. 給冰箱通電(如果需要)
  2. 開啟冰箱(公共方法)
  3. 放入東西 -子類重寫選擇放入什麼東西
  4. 關閉冰箱

程式碼

AbstractClass :

/**
 * 抽象類
 *
 * @author 七夜雪
 * @create 2018-11-24 11:02
 */
public abstract class AbstractClass {
    public void excute(){
        if (isNeedPrepare()) {
            prepare();
        }
        openFridge();
        put
(); closeFridge(); } public void prepare(){ System.out.println("給冰箱通電..."); } // 鉤子方法, 子類可以通過重寫這個方法控制prepare方法是否執行 public boolean isNeedPrepare(){ return false; } public void openFridge(){ System.out.println("開啟冰箱..."); } public abstract void put(); public void closeFridge(){ System.out.println("關閉冰箱..."); } }

ConcreteClass1, 重寫了鉤子方法 :

/**
 * 子類1 : 將大象放入冰箱
 *
 * @author 七夜雪
 * @create 2018-11-24 11:08
 */
public class ConcreteClass1 extends AbstractClass {

    @Override
    public void put() {
        System.out.println("將大象放入冰箱...");
    }

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

ConcreteClass2 :

/**
 * 子類2 : 將老虎放入冰箱
 *
 * @author 七夜雪
 * @create 2018-11-24 11:08
 */
public class ConcreteClass2 extends AbstractClass {

    @Override
    public void put() {
        System.out.println("將老虎放入冰箱...");
    }
}

測試程式碼 :

/**
 * @author 七夜雪
 * @create 2018-11-24 11:12
 */
public class Client {

    public static void main(String[] args) {
        AbstractClass cls1 = new ConcreteClass1();
        AbstractClass cls2 = new ConcreteClass2();
        cls1.excute();
        cls2.excute();
    }

}

測試結果:

給冰箱通電...
開啟冰箱...
將大象放入冰箱...
關閉冰箱...
開啟冰箱...
將老虎放入冰箱...
關閉冰箱...

本文參考:
慕課網<java設計模式精講 Debug 方式+記憶體分析>課程
四人幫<設計模式>