簡單的說,就是爲了不在多個子類實現某個算法的過程當中,應用程序開發人員寫錯了算法過程,而致使產生了錯誤的結果。咱們讓類庫開發人員本身寫一個固定的算法骨架(因而此模式只能適應於算法骨架基本肯定的應用場景!)。讓一部分全部類都公用的算法、步驟,在類庫中實現,而後讓不一樣的應用程序開發人員書寫適用於當前場景的部分步驟,而後調用父類的骨架方法,實現算法!java
好比下面的實戰1的銀行業務辦理程序,取號、業務結束給出評價,這兩個步驟是不一樣的應用程序不須要管理的,因而設置爲final的(在Java程序設計中是final,若是是c++程序設計則把函數實現寫成const便可!)。這些程序每每是一些和任何應用程序開發者無關的代碼,設置成final避免應用程序開發者無心中修改,致使了算法的結果錯誤!c++
好比下面的實戰2的數據分析程序,有些應用程序(子類)的應用場景下的數據,須要被加工再能被分析!可是有些數據是能夠直接拿來分析,好比:Excel的數據每每能夠在download後直接拿來處理,可是一些柱狀圖制類的數據須要二次加工後再處理!因此咱們能夠設置一個《鉤子函數》的hook方法,這種方法通常是返回布爾值的(boolean/bool)。若是大多數狀況是須要處理的,咱們就給這個hook方法默認返回一個false,避免有些應用程序開發者忘記處理而進入數據分析的流程!若是當前的數據是不須要二次加工的,則拓展的子類重寫該方法,返回true便可!算法
抽象方法在Java中,以關鍵字abstract來體現,有abstract標註的方法的類,稱之爲抽象類。若是是在c++中,則是設置純虛函數,有純虛函數的類是抽象類。這個方法咱們不能拿來實現,只須要在父類中定義,而後編譯器會強制要去應用程序的開發者去根據本身的實際狀況來實現抽象類。起到在運行期多態的效果!編程
讓算法固定,達到一種父類去調用子類的效果,符合《開閉原則》!
又利用繼承與多態,達到算法骨架的代碼複用的效果!設計模式
在銀行辦理業務這個算法流程(骨架)中,有一下幾個步驟:
① 取號
② 辦理業務
③ 業務結束,給出本次業務的評價markdown
其中有一些過程(方法)是靜態的,就是取號、業務結束,這兩個步驟。可是辦理業務的過程是動態的,不一樣的用戶角色,想辦理不一樣的業務!因此咱們只能把這個動態的過程(方法)抽象化,而固定不變的算法骨架。讓不一樣的須要辦理業務的角色類去繼承這個抽象類,而後在子類中重寫須要辦理的業務,在重寫結束後,再在調用的主類中去調用整個算法骨架process()。根據多態性,會根據子類的不一樣、實現的辦理業務的程序的不一樣,在相同的算法骨架中獲得不一樣的結果!ide
/** * 這個抽象類做爲模板方法的父類,完成銀行業務 * @author 不會編程的小良 * @version 1.0 * */ abstract class BaseBankTranscation { static int ServerId = 1; public void takeNumber(){ System.out.println("排隊取號ing……"); } /** * 這個抽象函數負責由子類根據具體業務完成重寫 * @author 不會編程的小良 * @version 1.0 * */ public abstract void transcation(); public void evalue(){ System.out.println("第 " + ServerId + " 次服務結束,完成評分……"); } public final void process(){ System.out.println("開始第 " + ServerId + " 次服務!"); takeNumber(); transcation(); evalue(); ServerId++; } }
/** * 這個子類負責重寫父類BaseBankTranscation的方法transcation(),完成取款業務 * @author 不會編程的小良 * @version 1.0 * */ class Deposite extends BaseBankTranscation { @Override public void transcation() { System.out.println("我要取款……"); } } /** * 這個子類負責重寫父類BaseBankTranscation的方法transcation(),完成存款業務 * @author 不會編程的小良 * @version 1.0 * */ class Withdraw extends BaseBankTranscation { @Override public void transcation() { System.out.println("我要存款……"); } } /** * 這個子類負責重寫父類BaseBankTranscation的方法transcation(),完成轉帳業務 * @author 不會編程的小良 * @version 1.0 * */ class Transfer extends BaseBankTranscation { @Override public void transcation() { System.out.println("我要轉帳……"); } }
/** * 這個主類負責完成各類銀行業務的辦理過程 * @author 不會編程的小良 * @version 1.0 * */ public class TemplateMethod { public static void main(String[] args){ int n = 3; BaseBankTranscation[] tran = new BaseBankTranscation[n]; for(int i = 0;i < n;++i){ switch (i % 3){ case 0: tran[i] = new Deposite(); break; case 1: tran[i] = new Withdraw(); break; case 2: tran[i] = new Transfer(); break; default: break; } } for(BaseBankTranscation item : tran) { item.process(); } } }
這個數據處理與分析分紅幾個步驟:函數
① 數據獲取(應用程序完成的抽象方法)
② 數據轉換成可處理的模式 (hook方法)
③ 數據分析(應用程序完成的抽象方法)
④ 數據分析的結果展現(hook方法)測試
abstract class BaseDataAnalysis { abstract void getData(); void connvertData(){ System.out.println("默認的數據轉換方法……"); } final void analysisData(){ System.out.println("完成數據分析工做……"); } void displayData(){ System.out.println("默認的輸出方式展現……"); } boolean isValid(){ return true; } void process(){ getData(); if(isValid()){ connvertData(); } analysisData(); displayData(); } }
class SubClass extends BaseDataAnalysis { @Override void getData(){ System.out.println("從JSON文件中獲取數據……"); } @Override void displayData(){ System.out.println("以餅狀圖展現的方法展現……"); } }
public class TemplateMethod { public static void main(String[] args){ BaseDataAnalysis sub = new SubClass(); sub.process(); } }
某銀行軟件的利息計算流程以下:atom
① 系統根據帳戶查詢用戶信息
② 根據用戶信息來判斷用戶類型
③ 不一樣類型的用戶使用不一樣的利息計算方式(如活期、按期)
④ 顯示利息
abstract class BankInterest { boolean isValidUser(String username, String password){ if("jiangzhengliang".equals(username) && "123456".equals(password)) { System.out.println("帳戶:" + username); System.out.println("密碼:" + password); return true; } else { return false; } } abstract void getAccountMethod(); final void display(){ System.out.println("顯示利息……"); } void process(String name, String psswd){ if(isValidUser(name, psswd)){ getAccountMethod(); display(); } } }
class CurrentAccount extends BankInterest { @Override void getAccountMethod() { System.out.println("我是活期貸款……"); } } class SavingAccount extends BankInterest { @Override void getAccountMethod() { System.out.println("我是按期貸款……"); } }
public class TemplateMethod { public static void main(String[] args){ BankInterest bank1 = new CurrentAccount(); bank1.process("jiangzhengliang", "123456"); BankInterest bank2 = new SavingAccount(); bank2.process("jiangzhengliang", "123456"); } }