Android設計模式系列--模板方法模式
模板方法,和單例模式是我認為GOF的23中最簡單的兩種模式。
但是我個人對模板方法的經典思想特別推崇,雖然模板方法在大對數情況下并不被推薦使用,但是這種通過父類調用子類的方法,使用繼承來改變算法的一部分,是面向對象的一種基本認識。
打比方說父親有很多理想,就行醫救人吧,但是父親醫術不行,只能靠兒子,兒子長大后遵從父親大志,春風拂面,妙手回春,實現了父親的理想,兒子做的事情早在出生前就定下來了,是父親之前久定好的模板。
認識到模板方法的這種思想,父類可以讓未知的子類去做它本身可能完成的不好或者根本完成不了的事情,對框架學習大有幫助。
本文以View中的draw方法為例,展開分析。
模板方法,TemplateMethod,光是學習這個模式,就會對你產生長遠影響的一個模式。
1.意圖
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
熱門詞匯:骨架 步驟 結構 延遲到子類
2.結構
定義了幾個步驟1,2,3等,在模板方法中按照一定的結構順序執行這些步驟。父類的方法可以有缺省實現,也可以是一個空實現,即所謂的鉤子操作。
結合實際情況,我們畫出View中draw方法涉及到的幾個步驟方法如下:
學習模板方法對于我們了解框架的基類實現,生命周期和流程控制非常有幫助,我覺得是務必要掌握的一個模式。
3.代碼
- public class View{
- /**
- * 鉤子操作,空實現
- */
- protected void onDraw(Canvas canvas) {
- }
- /**
- *鉤子操作,空實現
- */
- protected void dispatchDraw(Canvas canvas) {
- }
- //算法骨架
- public void draw(Canvas canvas) {
- if (!verticalEdges && !horizontalEdges) {
- // 步驟1
- if (!dirtyOpaque) onDraw(canvas);
- // 步驟2
- dispatchDraw(canvas);
- // 步驟3
- onDrawScrollBars(canvas);
- return;
- }
- }
- //... ...
- }
我們看看系統組件TextView的實現:
- public class TextView{
- @Override
- protected void onDraw(Canvas canvas) {
- //大量自定義實現代碼
- }
- }
如果我們自定義View的話,我們一般也是重寫onDraw方法即可:
- public class MyView extends View {
- public MyView(Context context) {
- super(context);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- }
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
- }
- }
4.效果
(1).模板方法是一種代碼復用的基本技術。它們在類庫中尤為重要,它們提取了類庫中的公共行為。
(2).模板方法導致一種方向控制結構,"好萊塢法則":"Don't call me,i will call you.",即一個父類調用子類的操作,而不是相反。
(3).模板調用操作的類型有具體的操作,具體的AbstracClass操作,原語操作,工廠方法,鉤子操作。少定義原語操作。
(4).android中對這些重定義操作的命名喜歡在方法前加一個前綴on。
(5).模板方法使用繼承來改變算法的一部分。策略模式使用委托來改變整個算法。