轉載自:https://www.cnblogs.com/zplogo/p/6428593.html
用抽象基類定義算法框架 RefreshBeverage
package com.pattern.template; /** * 抽象基類,為其他子類提供一個算法框架 提神飲料 * * */ public abstract class RefreshBeverage { /* * 制備飲料的模板方法 封裝了所有子類所遵循的算法框架 */ public final void prepareBeverageTemplate() { // 步驟一 將水煮沸 boilWater(); // 步驟二 泡制飲料 brew(); // 步驟三 將飲料倒入杯中 pourInCup(); if (isCustomerWantsCondiments()) { // 步驟四 加入調味料 addCondiments(); } } /* * Hook 鈎子函數,提供一個空的或者默認的實現 子類重寫該方法,可以自行決定是否掛鈎以及如何掛鈎 */ protected boolean isCustomerWantsCondiments() { return true; } // 因為將水煮沸和把飲料倒入杯中對所有子類是共同的行為,所以沒必要向子類過多開放,所以方法定義為private,這樣我們在進行子類編碼時可以減少復雜度。 // 這樣不需要關注細枝末節,我們只需要關注我們特定業務的實現,這就是模板方法模式的好處。可以封裝變與不變,將不變的固化在高層,隱藏其細節。 private void boilWater() { System.out.println("將水煮沸"); } private void pourInCup() { System.out.println("將飲料倒入杯中"); } /* * 泡制飲料brew()和加入調料品addCondiments()這兩個方法我們不知道它們在算法框架中的具體實現,因此定義為抽象方法, * 我們用protected進行修飾, 在子類中可見便於進行重寫。 */ protected abstract void brew(); protected abstract void addCondiments(); }
具體子類延遲實現步驟 Coffee
package com.pattern.template; /** * 提供制備咖啡的具體實現子類。 具體子類實現延遲步驟,滿足特定的業務需求。 * * */ public class Coffee extends RefreshBeverage { protected void brew() { System.out.println("步驟二 用沸水沖泡咖啡"); } protected void addCondiments() { System.out.println("步驟四 加入糖和牛奶"); } }
鈎子使子類更靈活 Tea
package com.pattern.template; public class Tea extends RefreshBeverage { protected void brew() { System.out.println("步驟二 用80度熱水浸泡茶葉5分鍾"); } protected void addCondiments() { System.out.println("步驟四 加入檸檬"); } protected boolean isCustomerWantsCondiments() { return false; } }
測試類 RefreshBeverageTest
package com.pattern.template; public class RefreshBeverageTest { public static void main(String[] args) { System.out.println("制備咖啡中······"); RefreshBeverage b1 = new Coffee(); b1.prepareBeverageTemplate(); System.out.println("咖啡好了········"); // 制備茶的測試代碼 System.out.println("\n*********************************"); System.out.println("制備茶水中······"); RefreshBeverage b2 = new Tea(); b2.prepareBeverageTemplate(); System.out.println("茶水好了······"); } }