模板方法-設計模式

在平常的工做生活中,有這些場景:(還有其餘生活場景)算法

  1. 去銀行辦理業務通常會通過四個流程:取號、排隊、辦理業務以及辦理完業務後對工做人員進行評分等流程,其中取號、排隊和對銀行工做人員進行評分的業務對每一個顧客都是一樣的,能夠在父類中實現;可是辦理的業務每一個人是不一樣的,取款、存款或者轉帳等,我的的具體業務能夠在子類中實現。
  2. 一我的天天起牀、吃飯、作事及睡覺等,其中作事情由於每一個人不一樣而異,所以咱們能夠將起牀,吃飯,以及睡覺定義爲父類,作事定義爲子類等
  3. 簡歷模板,論文模板,word模板等均可以定義爲父類,每一個人簡歷,論文,word模板又不一樣,能夠定義爲子類。

如下介紹模板方法模式將解決上述問題。設計模式

一 定義

模板方法(Template Method)模式定義爲:定義了一個操做中的算法骨架,而將算法的部分步驟延遲到子類,使得子類能夠不改變該算法結構的狀況下從新定義該算法的某些特定的步驟。是一種類行爲型模式。app

 

二 特色

模板方法模式的優缺點以下ide

優勢函數

  1. 封裝不變部分,擴展可變部分。不變部分的算法封裝到父類中去實現,而把可變部分算法由子類去繼承實現,便於子類擴展。
  2. 父類中提取了公共的代碼部分,便於代碼複用。
  3. 部分的方法是由子類實現,子類拓展相應的功能,符合了開閉原則。

缺點this

  1. 對每一個不一樣的實現都須要一個子類,致使了類的個數增長,系統變得龐大。
  2. 父類中的抽象方法是由子類實現,子類執行的結果也會影響到父類,提升了代碼的閱讀難度。

 

三 模板結構和實現

模板方法模式須要注意具體子類與抽象類之間的協議工做,它用到了虛函數的多態性技術以及反向控制技術。如今介紹其基本結構。spa

3.1 模板的結構

模板方法模式主要包含如下角色。設計

3.1.1 抽象類(abstract class)定義了算法的骨架,由一個模板方法和若干個基本的方法來構成。

  1. 模板方法:定義算法的骨架,按某種順序調用包含的方法。
  2. 基本方法:是算法中的一個步驟,包含了如下幾種類型。
  • 抽象方法:在抽象類中申明,是由子類去實現。
  • 具體方法:在抽象類中已經實現,在具體子類中去繼承或者重寫
  • 鉤子方法:在抽象類已經實現,包括用於判斷的邏輯以及須要子類重寫的空方法兩種。

拓展:釘子方法3d

就是在抽象類中定義一個方法,默認不作任何事,子類能夠根據實際狀況要不要覆蓋它,從而改變行爲,該方法稱爲「鉤子」。

3.1.2 具體子類(concrete class)實現抽象類中所定義的抽象方法和鉤子方法。

結構圖以下:code

 

3.2 模板的具體實現

模板方法的模式代碼以下

package templateMethod;
public class TemplateMethodPattern
{
    public static void main(String[] args)
    {
        AbstractClass tm=new ConcreteClass();
        tm.TemplateMethod();
    }
}
//抽象類
abstract class AbstractClass
{
    public void TemplateMethod() //模板方法
    {
        SpecificMethod();
        abstractMethod1();          
        abstractMethod2();
    }  
    public void SpecificMethod() //具體方法
    {
        System.out.println("抽象類中的具體方法被調用...");
    }   
    public abstract void abstractMethod1(); //抽象方法1
    public abstract void abstractMethod2(); //抽象方法2
}
//具體子類
class ConcreteClass extends AbstractClass
{
    public void abstractMethod1()
    {
        System.out.println("抽象方法1的實現被調用...");
    }   
    public void abstractMethod2()
    {
        System.out.println("抽象方法2的實現被調用...");
    }
}

程序的運行的結果以下

抽象類中的具體方法被調用...
抽象方法1的實現被調用...
抽象方法2的實現被調用...

 

四 應用實例

示例

模擬製做咖啡店家接受訂單的過程。父類Coffee定義了公共的方法,如研磨咖啡豆,同時定義了可變的部分。可是呢,有的消費者不喜歡加奶,有的不喜歡加糖,因此定義了鉤子方法isAddMilk和isAddSugar判斷是否要加奶加糖,而子類根據實際須要判斷是否要加奶加糖。

Coffee(父類-抽象)

public abstract class Coffee {
    boolean addSugarFlag = false;
    boolean addMilkFlag = false;
    public boolean isAddMilkFlag() {
        return addMilkFlag;
    }
    public boolean isAddSugarFlag() {
        return addSugarFlag;
    }
    Coffee prepareHotWater(){
        System.out.println("準備熱水");
        return this;
    }
    Coffee grindCoffeeBean(){
        System.out.println("研磨咖啡豆");
        return this;
    }
    void addSugar(){
        System.out.println("加糖");
    }
    void addMilk(){
        System.out.println("加奶");
    }
    Coffee make(String coffeeName){
        Coffee coffee = prepareHotWater().grindCoffeeBean();
        if(isAddMilkFlag()){
            coffee.addMilk();
        }
        if(isAddSugarFlag()){
            coffee.addSugar();
        }
        System.out.println("製做完成!這是一杯"
                + (isAddSugarFlag() ? "" : "不加") + "糖,"
                + (isAddMilkFlag() ? "" : "不加") + ""
                + "" + coffeeName);
        return coffee;
    }
}

 Cap類和Latte類

public class Cap extends Coffee {
    String coffeeName = "卡布奇諾";
    Coffee make(){
        return super.make(this.coffeeName);
    }
    @Override
    public boolean isAddSugarFlag() {
        return true;
    }
}

public class Latte extends Coffee {
    String coffeeName = "拿鐵";
    Coffee make(){
        return super.make(this.coffeeName);
    }
    @Override
    public boolean isAddMilkFlag() {
        return true;
    }
    @Override
    public boolean isAddSugarFlag() {
        return true;
    }
}

Test類

public class Test {
    public static void main(String[] args) {
        System.out.println("******  下訂單:一杯加糖,不加奶的熱卡布奇諾  ******");
        Cap cappuccino = new Cap();
        cappuccino.make();
        System.out.println("******  下訂單:一杯加糖,加奶的熱拿鐵  ******");
        Latte latte = new Latte();
        latte.make();
    }
}

輸出結果

******  下訂單:一杯加糖,不加奶的熱卡布奇諾  ******
準備熱水
研磨咖啡豆
加糖
製做完成!這是一杯加糖,不加奶的卡布奇諾
******  下訂單:一杯加糖,加奶的熱拿鐵  ******
準備熱水

 

五 總結

開發過程當中,使用模板方法模式很方便將共有的代碼提取出來,可以下降代碼的冗餘,提升了開發的效率,在開發中應該100%會被用到,或者用到了你殊不知道。但願經過本篇博客,你們可以加深對模板方法模式的理解。下一次,咱們將講述設計模式-策略模式,歡迎關注,會實時更新博客!!!

相關文章
相關標籤/搜索