在平常的工做生活中,有這些場景:(還有其餘生活場景)算法
如下介紹模板方法模式將解決上述問題。設計模式
模板方法(Template Method)模式定義爲:定義了一個操做中的算法骨架,而將算法的部分步驟延遲到子類,使得子類能夠不改變該算法結構的狀況下從新定義該算法的某些特定的步驟。是一種類行爲型模式。app
模板方法模式的優缺點以下ide
優勢函數
缺點this
模板方法模式須要注意具體子類與抽象類之間的協議工做,它用到了虛函數的多態性技術以及反向控制技術。如今介紹其基本結構。spa
模板方法模式主要包含如下角色。設計
拓展:釘子方法3d
就是在抽象類中定義一個方法,默認不作任何事,子類能夠根據實際狀況要不要覆蓋它,從而改變行爲,該方法稱爲「鉤子」。
結構圖以下:code
模板方法的模式代碼以下
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%會被用到,或者用到了你殊不知道。但願經過本篇博客,你們可以加深對模板方法模式的理解。下一次,咱們將講述設計模式-策略模式,歡迎關注,會實時更新博客!!!