介紹
在面向?qū)ο箝_發(fā)過程中蔚鸥,通常會遇到一個這樣的問題,我們知道一個算法所需的關(guān)鍵步驟捧弃,并確定了這些步驟的執(zhí)行順序赠叼,但是,某些步驟的具體實現(xiàn)是未知的违霞,或者說某些步驟的實現(xiàn)是會隨著環(huán)境的變化而變化的嘴办。這類問題的解決方案就是模板方式方法。
定義
定義一個操作中的算法的框架买鸽,而將一些步驟延遲到子類中涧郊,使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義算法的某些特定步驟。
使用場景
- 多個子類有公有的方法眼五,并且邏輯基本相同
- 重要妆艘、復(fù)雜的算法彤灶,可以把核心算法設(shè)計為模板方法,周邊的相關(guān)細(xì)節(jié)功能則有各個子類實現(xiàn)
- 重構(gòu)時双仍,模板方法模式是一個經(jīng)常使用的模式枢希,把相同的代碼抽到父類中桌吃,然后通過鉤子函數(shù)約束其行為朱沃。
角色介紹
ABSTemplate 抽象類,定義了一套算法框架茅诱,并提供了一個鉤子函數(shù)逗物,鉤子函數(shù)中按算法框架的邏輯流程調(diào)用各步驟方法,鉤子函數(shù)是 final 的瑟俭,保證邏輯流程不能被子類修改翎卓,子類只能改變某一步驟中的具體實現(xiàn),從而保證邏輯流程的穩(wěn)定性摆寄。其中的算法步驟我們稱為模板方法失暴。
ConcreteImpl 具體實現(xiàn)類,負(fù)責(zé)算法框架各個步驟的具體實現(xiàn)
Android 源碼中的模板方法
在 Android 中微饥,AsyncTask 是一個比較常用的類逗扒,這個類就是用了模板方法模式。使用 AsyncTask 時欠橘,我們把耗時方法放入 doInBackground 方法中矩肩,在 doInBackground 之前,還可以在 onPreExcute 方法中做一些初始化操作肃续,doInBackground 執(zhí)行完成后黍檩,會執(zhí)行 onPostExcute 方法。而我們只需要構(gòu)建 AsyncTask 對象始锚,然后執(zhí)行 execute 方法即可刽酱。可以看到整個過程就是一個框架瞧捌,具體的實現(xiàn)都需要子類來完成棵里,并且執(zhí)行的算法框架時固定的。
總結(jié)
模板方法用 4 個字概括就是察郁,流程封裝衍慎。也就是把某個固定的流程封裝到一個 final 函數(shù)中,并且讓子類能夠定制這個流程中的某些或所有步驟皮钠,這就要求父類提取共用的代碼稳捆,提升代碼的復(fù)用率,同時也帶來了更好的擴(kuò)展性麦轰。
優(yōu)點
- 封裝不變代碼乔夯,擴(kuò)展可變部分
- 提取公共代碼部分砖织,便于維護(hù)
缺點
模板方法會帶來代碼閱讀的難度,讓用戶覺得難以理解