實際開發中經常會遇到,代碼骨架相似甚至相同,只是具體的實現不同的場景。例如:流程都有開啓、編輯、駁回、結束。每一個流程都包含這幾個步驟,不一樣的是不一樣的流程實例它們的內容不同。共享單車都是先開鎖、騎行、上鎖、付款。這些大的步驟固定,不一樣的是每一個實例的具體實現細節不同。這些相似的業務咱們均可以使用模板模式實現。爲何要使用模板模式以及如何使用呢?java
定義:在模板模式(Template Pattern)中,一個抽象類公開定義了執行它的方法的方式/模板。它的子類能夠按須要重寫方法實現,但調用將以抽象類中定義的方式進行。這種類型的設計模式屬於行爲型模式。
意圖:定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟
主要解決:一些方法通用,卻在每個子類都從新寫了這一方法。
什麼時候使用:有一些通用的方法。
如何解決:將這些通用算法抽象出來。
關鍵代碼:在抽象類實現,其餘步驟在子類實現。算法
咱們以生活中買菜作飯的例子來寫個Demo,燒飯通常都是買菜、洗菜、烹飪、裝盤四大過程。中國自古有八大菜系,製做方式確定都避不開這四個過程。那在模板模式中如何實現呢?
建立一個抽象類,它的模板方法被設置爲 final。爲防止惡意操做,通常模板方法都加上 final 關鍵詞。設計模式
public abstract class AbstractCookingService { //買菜 protected abstract void shopping(); //清洗 protected abstract void wash(); //烹飪 protected abstract void cooking(); //裝盤 protected abstract void dishedUp(); public final void process() { shopping(); wash(); cooking(); dishedUp(); } }
建立實現了上述抽象類的子類。
// 徽菜烹飪ide
/** * 徽菜製做大廚 */ public class HuiCaiChef extends AbstractCookingService { @Override protected void shopping() { System.out.println("買菜:新鮮魚一條,紅辣椒五兩"); } @Override protected void wash() { System.out.println("清洗:紅椒洗淨切片,魚頭半分"); } @Override protected void cooking() { System.out.println("烹飪:魚頭水蒸,辣椒過油"); } @Override protected void dishedUp() { System.out.println("裝盤:用長形盤子裝盛"); } }
// 川菜烹製ui
/** * 川菜製做大廚 */ public class HuiCaiChef extends AbstractCookingService { @Override protected void shopping() { System.out.println("買菜:黑豬肉一斤,蒜頭5個"); } @Override protected void wash() { System.out.println("清洗:豬肉洗淨,蒜頭去皮"); } @Override protected void cooking() { System.out.println("烹飪:大火翻炒,慢火悶油"); } @Override protected void dishedUp() { System.out.println("裝盤:深碗盛起,熱油澆拌"); } }
使用 TemplatePatternDemo 類執行模板方法 process() 來演示烹飪的定義方式。設計
public class TemplatePatternDemo { public static void main(String[] args) { System.out.println("----------川菜製做------------"); AbstractCookingService chuanCaiService = new ChuanCaiChef(); chuanCaiService.process(); System.out.println("-----------徽菜製做-----------"); AbstractCookingService huiCaiService = new HuiCaiChef(); huiCaiService.process(); } }
執行程序,輸出結果:code
----------川菜製做------------ 買菜:新鮮魚一條,紅辣椒五兩 清洗:紅椒洗淨切片,魚頭半分 烹飪:魚頭水蒸,辣椒過油 裝盤:用長形盤子裝盛 -----------徽菜製做----------- 買菜:黑豬肉一斤,蒜頭5個 清洗:豬肉洗淨,蒜頭去皮 烹飪:大火翻炒,慢火悶油 裝盤:深碗盛起,熱油澆拌
從以上實例能夠看出,其實模板模式也沒什麼高深莫測的,簡單來講就是三大步驟:繼承
從以上的分析和Demo咱們能夠看到,模板方法提升了咱們的代碼的可維護性和可擴展性。有優勢也有缺點。
優勢: 一、封裝不變部分,擴展可變部分。 二、提取公共代碼,便於維護。 三、行爲由父類控制,子類實現。
缺點:每個不一樣的實現都須要一個子類來實現,致使類的個數增長,使得系統更加龐大。
使用場景: 一、有多個子類共有的方法,且邏輯相同。 二、重要的、複雜的方法,能夠考慮做爲模板方法。開發