本質(zhì)
固定算法骨架
模板方法主要是通過(guò)制定規(guī)范模板逸贾,把算法步驟固定下來(lái)立镶,至于誰(shuí)來(lái)實(shí)現(xiàn)师逸,首先模板可以自己提供默認(rèn)實(shí)現(xiàn)司倚,另外也可以由子類去實(shí)現(xiàn),還可以通過(guò)回調(diào)機(jī)制由其他類來(lái)實(shí)現(xiàn)篓像。
模板方法固定算法用來(lái)約束子類行為动知,并在特定的擴(kuò)展點(diǎn)上來(lái)讓子類進(jìn)行功能拓展,很好的體現(xiàn)了開(kāi)閉原則和里氏替換原則员辩。首先從設(shè)計(jì)上分離變與不變盒粮,把不變的部分抽取到父類中,比如算法股價(jià)屈暗,一些公共的拆讯,固定的實(shí)現(xiàn)等。如果想拓展新的功能养叛,由子類去實(shí)現(xiàn)可變化的步驟种呐。另外通過(guò)切換不同的具體實(shí)現(xiàn)來(lái)切換不同的功能。
例子
Android系統(tǒng)中AsyncTask就是模板方法的具體實(shí)現(xiàn)弃甥。它固定了算法爽室,比如按順序調(diào)用onPreExecute() , doInBackground(),onPostExecute() ?這三個(gè)方法的具體實(shí)現(xiàn)放在子類中,看源碼
這三個(gè)方法基本調(diào)用順序淆攻,來(lái)看源碼部分
我們?cè)谑褂肁syncTask時(shí)調(diào)用execute(Params ... params)時(shí)就是在調(diào)用這個(gè)方法 源碼
exec.execute(mFuture)里面的
所以我們從上面例子中看到這就是模板方法模式的很好的體現(xiàn)阔墩。
實(shí)例
我們的在寫(xiě)Android時(shí)經(jīng)常會(huì)抽取一個(gè)父類比如 BaseActiviy . 這個(gè)類主要是做非業(yè)務(wù)實(shí)現(xiàn),處理公共的動(dòng)作瓶珊,固定算法啸箫。
例如我們App一般頂部會(huì)有一個(gè)Title,長(zhǎng)度是屏幕長(zhǎng)伞芹,高度50dp左右忘苛,會(huì)提示當(dāng)前是在哪個(gè)頁(yè)面。例如
左邊是返回到上一頁(yè)面唱较,右邊是分享扎唾,中間是提示。這種通用的Title南缓,最好是放在父類里⌒赜觯現(xiàn)在講一下如何實(shí)現(xiàn)。首先看父類
注釋寫(xiě)的很清楚汉形,BaseActivity的布局也很簡(jiǎn)單纸镊。
看一下子類現(xiàn)在的實(shí)現(xiàn)
看到了吧倍阐,按照了父類定義的固定算法股價(jià),真正的實(shí)現(xiàn)放在了子類里薄腻。
那么想一個(gè)現(xiàn)在常見(jiàn)的問(wèn)題收捣,就是每個(gè)同學(xué)肯定有自己維護(hù)的一套jar的列表届案,也叫底層功能模塊庵楷。比如 圖片加載緩存框架(Freso,Glide,UIL..) ? ?又比如網(wǎng)絡(luò)框架(Volley,Retrofit, ?Okhttp+volley...) ? ?我們雖然做了一層實(shí)現(xiàn)的封裝,但是似乎與底層API結(jié)合的太緊密了楣颠,無(wú)法做到一鍵切換底層庫(kù)尽纽。如果想隨時(shí)隨地更換底層jar,那么模板方法模式就非常的適合童漩,看下圖:
這樣當(dāng)我們想做切換弄贿,增刪改,底層圖片支持時(shí)就異常容易了矫膨。只要抽取公共功能到第一層差凹,讓子類自己去實(shí)現(xiàn)底層就可以了。
補(bǔ)充知識(shí)
什么時(shí)候使用抽象類侧馅?既要約束子類的行為危尿,又要為子類提供公共功能 的時(shí)候使用
抽象類是用 abstract 修飾的類: 抽象類不一定含有抽象方法,但有抽象方法的一定是抽象類