設計模式之模板方法

1、定義

在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類能夠在不改變算法結構的狀況下,從新定義算法中的某些步驟.java

2、核心思想

一、這個模式是用來建立一個算法的模板算法

二、模板方法將算法定義成一組步驟,其中的任何步驟均可以是抽象的,由子類負責實現ide

三、確保算法的結構保持不變,同時由子類提供部分實現spa

3、相關設計原則

好萊塢原則

一、別調用(打電話給)咱們,咱們會調用(打電話給)你設計

二、用於防止依賴腐敗code

三、要不要用你,高層組件說了算orm

四、好萊塢原則讓底層組件被掛鉤進計算中,而又不會讓高層組件依賴底層組件 ip

鉤子

一、鉤子是一種被聲明在抽象類中的方法,但只有空的或者默認的實現。鉤子的存在可讓子類有能力對算法的不一樣點進行鉤掛ci

二、有了鉤子,咱們可讓模板方法中的程序決定是否調用模板方法中的某些方法it


4、使用場景

一、茶和咖啡的沖泡方式

茶:(1)把誰煮沸(2)用沸水沖泡咖啡(3)把咖啡倒進杯子(4)加糖和牛奶

咖啡:(1)把誰煮沸(2)用沸水浸泡茶葉(3)把茶倒進杯子(4)加檸檬

二、觀察場景

兩種沖泡方式有相同的地方,也有不一樣的地方


5、代碼實現

package com.fengshu.limanman;
 
/**
 * 
 * 一、理解模板方法 二、理解好萊塢原則 三、理解鉤子的用法
 * 
 * @author 李慢慢
 *
 */
public class Temple {
    public static void main(String[] args) {
        CaffeineBeverage caffeineBeverage = new Coffee();
        caffeineBeverage.pripareRecipe();
    }
}
 
/**
 * 製做咖啡因飲料的模板方法
 *
 */
abstract class CaffeineBeverage {
 
    /**
     * final 確保算法的結構保持不變,也體現了好萊塢設計原則,讓子類沒辦法直接調用父類(高層組件方法),只能由高層組件來調用子類實現的方法
     */
    final void pripareRecipe() {
        boilWater();
        brew();
        pourInCup();
        // 鉤子決定子類是否執行模板中的某些方法
        if (needCondiments()) {
            addCondiments();
        }
    }
 
    /**
     * 模板方法將算法定義成一組步驟,其中的任何步驟均可以是抽象的,由子類負責實現
     */
    abstract void brew();
 
    /**
     * 模板方法將一部分的實現延遲到了子類中
     */
    abstract void addCondiments();
 
    void boilWater() {
        System.out.println("Boiling water");
    }
 
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
 
    /**
     * 使用了鉤子默認true,由子類決定是否進行覆蓋
     * 
     * @return
     */
    boolean needCondiments() {
        return true;
    }
}
 
class Coffee extends CaffeineBeverage {
 
    /**
     * 模板方法使得子類能夠在不改變算法結構的狀況下,從新定義算法中的某些步驟
     *
     */
    @Override
    void boilWater() {
        System.out.println("Boiling water  long long");
    }
 
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
 
    /**
     * 有了鉤子,我可以決定要不要覆蓋方法。若是我不提供在本身 的方法,抽象類會提供一個默認的實現
     */
    @Override
    boolean needCondiments() {
        return false;
    }
 
}
 
class Tea extends CaffeineBeverage {
 
    @Override
    void brew() {
        System.out.println("steeping the tea");
    }
 
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}
相關文章
相關標籤/搜索