模板方法模式,名字就很直接,也很容易理解。什么是模板,模板就是一套固定格式。我們可以想象一個普通員工的一天的上班模板:去公司上班->工作->下班回家。
對于每一個員工來說,這三個步驟的具體內容是不一樣的,但是流程都是這樣的。
在開發中也會有這種情況,架構師或者高級開發人員寫好一些方法流程,規定方法名,方法輸出,執行順序等等,但是方法體是空的,留給初級的開發人員去填寫具體的實現功能。
而且這樣一套模板用不同的平臺語言實現就可以生成不同平臺的產品。這些解決方案都可以稱為模板方法模式。
定義
定義一個操作中算法的框架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
使用場景
- 多個邏輯有公有的方法,且邏輯基本相同。
- 重要、復雜的算法,可以把核心算法設計為模板方法,周邊的相關細節功能由各個子類實現。
- 重構時經常會用到模板方法,把相同的代碼抽取到父類中,然后通過鉤子方法約束其行為。
UML
UML圖很簡單
- Abstemplate:抽象類,定義了一套算法框架
- ConcreteImplA:具體實現類A
- ConcreteImplB:具體實現類B
簡單實例
這里以打開計算機的過程為例。雖然計算機有不同的系統和用處,但是計算機的開機過程都是一樣的。
啟動電源-->檢查系統狀態-->進入操作系統-->驗證身份登錄
定義一個抽象的計算機模板
public abstract class AbsComputer {
protected void powerOn(){
System.out.println("打開電源");
}
protected void checkHardware(){
System.out.println("檢查硬件");
}
protected void loadOS(){
System.out.println("載入操作系統");
}
protected void login(){
System.out.println("用戶登錄");
}
//這里不允許重寫,必須按這個順序來
public final void startUp(){
System.out.println("開機 START");
checkHardware();
loadOS();
login();
System.out.println("開機 END");
}
}
實現一個程序員計算機
public class CoderComputer extends AbsComputer {
@Override
protected void login() {
super.login();
System.out.println("程序員計算機需要驗證用戶名和密碼");
}
}
實現一個牛逼計算機
public class NBComputer extends AbsComputer {
@Override
protected void checkHardware() {
super.checkHardware();
System.out.println("牛逼的計算機要驗證硬件防火墻");
}
@Override
protected void login() {
super.login();
System.out.println("牛逼的計算機要驗證指紋");
}
}
使用:
public class Client {
public static void main(String[] args) {
CoderComputer coderComputer = new CoderComputer();
coderComputer.powerOn();
coderComputer.startUp();
System.out.println("--------");
NBComputer nbComputer = new NBComputer();
nbComputer.powerOn();
nbComputer.startUp();
}
}
輸出:
子類都只能修改部分具體的實現,整體的邏輯流程是不允許修改的。
Android中的模板方法
常用的AsyncTask的使用方法是這樣的:
class MyAsynctask extends AsyncTask{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(Object[] params) {
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
}
}
通常要重寫者三個方法。AsyncTask的執行過程就是一個邏輯流程,在這個過程中會在適當的時候執行者三個方法,這個過程是固定的。但是子類可以通過重寫者三個方法來改變具體的執行內容。
總結
模板方法模式就是流程封裝,父類提取公用代碼,子類實現部分或全部步驟。父類規定了整體流程。
優點
- 封裝不變部分,擴展可變部分,符合開閉原則。
- 提取公共代碼,提高代碼復用率,利于維護。
缺點
- 用戶閱讀代碼時只看子類會覺得難以理解,因為子類中并不是一個完整的邏輯。