關於模板方法和策略模式的一點思考

2022-02-12 05:38:15 字數 2255 閱讀 8945

該隨筆的思想原點,應該算是在兩三年前了。當時和一前同事聊天、不知怎得就聊到了http訪問。

一、我記得他和我說過的第一句話,大概是:有沒有已經封裝好的、比較強大的httputil。也可能是受業務的影響(介面對內)、我當時接觸到的http訪問,大多比較「規範」,至少有乙個介面約束在約定著某些東西,不至於一會傳遞json,返回json, 一會又要傳遞xml,返回xml,甚至更奇葩的是,上傳個檔案、返回0或者1。如果真出現這樣的狀態,httputil依然能夠方便、靈活的適應著各種情況、我想這個util已經絕對強大了。而不巧的是,我同事那裡恰恰就是要滿足這樣奇葩的需求(和多個第三方進行系統對接)。

記得當時,面對這個問題時、我的第一意識:模板方法,並且似乎還在**見過這樣的使用方式。因為:整個http訪問的流程無外乎:

1、根據url建立請求物件,

2、設定請求引數,比如:不使用快取、設定header、cookie、超時時間 等等。

3、傳送資料,比如:post方法。

4、建立響應物件

5、接收資料。

6、獲取響應引數

7、初上述流程之外,無論是作為util、還是作為乙個強大的框架、很有可能還進行異常處理、日誌記錄等附加流程。

定義乙個演算法主幹、將步驟的細節實現延遲到子類,使得。在基類中復用**,形成乙個繼承體系,最終,只需要在最底層的類中、重寫函式處理三件事,乙個是提供請求位址,第二個是提供請求資料,第三個是處理響應資料,當然這樣處理、預設認為請求方法已經被封裝了。這麼一想,這個方案似乎不錯啊?

但是,如果系統中有成百上千個需要對接的介面,結果會咋樣?成百上千個類? 似乎也可以接受?

再複雜一點,如果請求的資料可能是表單、json、xml、檔案,而響應的資料也有可能是這些、甚至更多,那麼面對這樣的需求,如果繼續使用模板方法會咋樣?仔細想想,繼承可以實現**復用、但面對上述的需求,如果只是使用繼承、能實現高效復用嗎(尤其是面對單繼承的情況下)?請注意在這裡處理請求資料 和 處理響應資料是兩個變化點、並且是兩個變化點獨立變化,即請求資料可能是模擬的乙個表單,而響應資料可能是一段json、一段xml、一張image(驗證碼), 甚至可能是乙個檔案 或者乙個壓縮包(多個檔案)。而如果請求資料是json、xml 等等格式,響應資料依然有可能是如上的情況。也就說一旦遇到多個變化點獨立變化時,單繼承瞬間就被打回原形了。

再多浪費一點思考的精力,如果將大量的可復用**放入基類(訪問許可權是受保護的),然後在子類中選擇性進行呼叫,似乎也可以解決上文提到的「多個變化點獨立變化」的問題,但是那樣一來,基類會極其臃腫,靈活性會大大降低,並且多種資料處理方式之間的耦合性會成指數級上公升【這算是一種更失敗的設計】。  

二、當我提出了模板方法之後,我問同事,有什麼想法?他的回答是,似乎覺得使用了策略模式之後,模板方法就不需要了,或者說模板方法可以完全被策略模式所替代。並且我當時也有乙個錯誤認知,模板方法 = 一組策略模式。在**效果上來看,模板方法 和 一組策略模式 確實是可以劃等號的,但兩者真的「相等」嗎? 如果相等,那麼模板方法似乎沒必要存在了?我們先看一下兩者的意圖吧:

模板方法的意圖:定義乙個演算法流程,將一些特定步驟的具體實現、延遲到子類。使得可以在不改變演算法流程的情況下,通過不同的子類、來實現「定製」流程中的特定的步驟。

策略模式的意圖:使不同的演算法可以被相互替換,而不影響客戶端的使用。

在意圖上看,模板方法更加強調:

1)定義一條線(演算法流程),線上的多個點是可以變化的(具體實現在子類中完成),線上的多個點一定是會被執行的,並且一定是按照特定流程被執行的。

2)演算法流程只有唯一的入口,對於點的訪問是受限的【通常用受保護的虛函式來定義可變點】。

策略模式更注重於: 乙個「策略」是乙個

整體的(完整的)

演算法,演算法是可以被整體替換的。而模板方法只能被替換其中的特定點,演算法流程是固定不可變的。

在這樣的細節上看來,模板方法 和 一組策略模式 是不可以劃等號的。

三、在這個「古老」的模式——模板方法面前,似乎 「優先使用物件組合,而不是繼承」 的策略模式 很是趾高氣昂?我個人還是覺得、各有優缺,只是各自適應的場景不一樣而已。當遇到「多個變化點獨立變化」時,這時就需要策略模式來救場了,如若不然,原有架構可以很好地進行維護和擴充套件,那還有必要去大動干戈、非要去找到那個暫時最完美的答案嗎?似乎沒有吧。

策略模式的一點自我總結

package cn.zhao.moshi.strategy public inte ce idiscountstrategy package cn.zhao.moshi.strategy 按使用者所買物品單價進行折扣 public class impldiscountbyprice impleme...

關於設計模式的一點感想

過去對於軟體當中復用的思想有概念,但卻沒有太深刻的體會,有時候在 裡面多處呼叫了同乙個函式,就認為這個就是軟體的復用了。甚至和別人一聊起 物件導向 來,也會說到 抽象 繼承 封裝 多型 設計模式 資料結構與演算法 等等名詞,但卻真的沒有一種內心的深刻體驗,也很少想什麼時候應該用 抽象 或 介面 多型...

關於設計模式的一點想法

軟體開發的理想是開發出高內聚 低耦合的軟體,學習 掌握優秀的設計模式並在實際開發過程中合理地加以運用,可以開發出可讀性 可維護性和可測性強的程式,降低 的冗餘性。由此想到,我們在軟體開發過程中,經常過分關注於具體的實現細節,忽略了考慮軟體設計上是否合理 是否存在更加可取的設計模式,而有意識地思考設計...