Android設(shè)計(jì)模式系列--模板方法模式
模板方法,和單例模式是我認(rèn)為GOF的23中最簡(jiǎn)單的兩種模式。
但是我個(gè)人對(duì)模板方法的經(jīng)典思想特別推崇,雖然模板方法在大對(duì)數(shù)情況下并不被推薦使用,但是這種通過父類調(diào)用子類的方法,使用繼承來(lái)改變算法的一部分,是面向?qū)ο蟮囊环N基本認(rèn)識(shí)。
打比方說(shuō)父親有很多理想,就行醫(yī)救人吧,但是父親醫(yī)術(shù)不行,只能靠?jī)鹤?,兒子長(zhǎng)大后遵從父親大志,春風(fēng)拂面,妙手回春,實(shí)現(xiàn)了父親的理想,兒子做的事情早在出生前就定下來(lái)了,是父親之前久定好的模板。
認(rèn)識(shí)到模板方法的這種思想,父類可以讓未知的子類去做它本身可能完成的不好或者根本完成不了的事情,對(duì)框架學(xué)習(xí)大有幫助。
本文以View中的draw方法為例,展開分析。
模板方法,TemplateMethod,光是學(xué)習(xí)這個(gè)模式,就會(huì)對(duì)你產(chǎn)生長(zhǎng)遠(yuǎn)影響的一個(gè)模式。
1.意圖
定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。 
熱門詞匯:骨架  步驟 結(jié)構(gòu) 延遲到子類 
2.結(jié)構(gòu)

定義了幾個(gè)步驟1,2,3等,在模板方法中按照一定的結(jié)構(gòu)順序執(zhí)行這些步驟。父類的方法可以有缺省實(shí)現(xiàn),也可以是一個(gè)空實(shí)現(xiàn),即所謂的鉤子操作。
結(jié)合實(shí)際情況,我們畫出View中draw方法涉及到的幾個(gè)步驟方法如下:

學(xué)習(xí)模板方法對(duì)于我們了解框架的基類實(shí)現(xiàn),生命周期和流程控制非常有幫助,我覺得是務(wù)必要掌握的一個(gè)模式。
3.代碼
- public class View{
 - /**
 - * 鉤子操作,空實(shí)現(xiàn)
 - */
 - protected void onDraw(Canvas canvas) {
 - }
 - /**
 - *鉤子操作,空實(shí)現(xiàn)
 - */
 - 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;
 - }
 - }
 - //... ...
 - }
 
我們看看系統(tǒng)組件TextView的實(shí)現(xiàn):
- public class TextView{
 - @Override
 - protected void onDraw(Canvas canvas) {
 - //大量自定義實(shí)現(xiàn)代碼
 - }
 - }
 
如果我們自定義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).模板方法是一種代碼復(fù)用的基本技術(shù)。它們?cè)陬悗?kù)中尤為重要,它們提取了類庫(kù)中的公共行為。
(2).模板方法導(dǎo)致一種方向控制結(jié)構(gòu),"好萊塢法則":"Don't  call me,i will call  you.",即一個(gè)父類調(diào)用子類的操作,而不是相反。
(3).模板調(diào)用操作的類型有具體的操作,具體的AbstracClass操作,原語(yǔ)操作,工廠方法,鉤子操作。少定義原語(yǔ)操作。
(4).android中對(duì)這些重定義操作的命名喜歡在方法前加一個(gè)前綴on。
(5).模板方法使用繼承來(lái)改變算法的一部分。策略模式使用委托來(lái)改變整個(gè)算法。















 
 
 









 
 
 
 