敏捷軟件開發 第十三章~第十七章
這幾章主要講了幾個設計模式,分別是:
Command (命令模式)
Active Object (主動對象模式)
Template Method (模板方法模式)
Strategy (策略模式)
Facade(外觀模式)
Mediator (中介者模式)
Singleton (單例模式)
Monostate (單態模式)
Null Object (空對象模式)
下面分別就我做了了解的模式進行介紹,分別是:
Command (命令模式)
Template Method (模板方法模式)
Strategy (策略模式)
Facade(外觀模式)
Singleton (單例模式)
Command (命令模式)
我認為命令模式的主要作用在於兩點:
1、解耦命令調用者(Invoker)和命令執行者(Receiver),讓他們獨立的變化
2、對需要重復使用的功能進行封裝,以便實現一次書寫,多次使用
命令調用者(Invoker)使用 Command 接口來調用 Receiver 來處理任務,而 Receiver 通過被 Command 接口的實現類調用,來完成任務
這樣的話,Invoker 和 Receiver 可以獨立地變化
且當有日誌等系統性的功能需要實現的時候,可以直接在 Invoker 中加入相關代碼,而不用每次調用命令的時候,都在 Client 中實現同樣的代碼
整個調用鏈:Client → Invoker(命令調用者,也是封裝變化的地方) → Command ← ConcreteCommand(實現 Command 接口) ← Receiver
Template Method (模板方法模式)
我認為的要點:
1、使用抽象類封裝算法(這裏的算法指控制整個流程的代碼)
2、將流程中每一步,交由具體的類去實現
調用鏈
abstract base class ← implement class
abstract base class 中定義了包含算法的實際(非抽象)方法,定義了流程中每一步的抽象方法
implement class 繼承 abstract base class,實現了其中的抽象方法
這樣,算法就可以被復用了
但是,有個缺點,那就是耦合性較高,要使用算法的話,必須繼承抽象基類(abstract base class)
於是,就有了策略模式,對其進行改進
Strategy (策略模式)
使用模板方法模式時,為了實現算法的復用,必須要繼承包含算法的抽象基類,耦合性較高
對此,策略模式使用了另一種方式實現算法的復用
即,將抽象的流程方法從抽象基類(abstract base class)中分離出去,分離到一個接口(interface)中
這樣,抽象基類,就變成了只包含非抽象方法的非抽象基類(base class),而對於要復用算法的類而言,它只需要實現定義了那些抽象流程方法的接口即可
在使用時,客戶端偽代碼如下:
// 創建基類實例(利用帶參的構造方法傳入具體的實現類)
// 使用基類實例,調用包含算法代碼的方法
這樣,由於使用了接口隔離了算法和具體的實現代碼
要使用某個算法的時候,就不用繼承包含該算法的類了
而且,不僅算法可以復用,連具體的實現代碼都可以復用(同類型的算法,使用同一份實現代碼),即,在客戶端代碼中,創建的基類可以變,傳入的實現類也可以變
Template Method (模板方法模式) 和 Strategy (策略模式) 的比較
以下是我個人的一些聯想和思考,不一定正確
聯想到,學習多線程的時候,兩種創建線程的方式,是不是分別對應著模板方法模式和策略模式呢? 每次到最後,都是用 Thread 類的 start() 方法,那麽,是不是 start() 方法裏封裝的就是算法呢? 註:Thread 裏面,run() 方法應該不是封裝算法的(這點跟書(指《敏捷軟件開發》)上不同,書上使用 run() 方法封裝算法的。) 書中的 run() 方法對應著 Thread 類裏面的 start() 方法,然後 init()、idle()、cleanup() 對應的是 Thread 類裏面的 run() 方法 在策略模式中, ApplicationRunner 對應著 Thread Application 對應著 Runnable FtocStrategy 對應著某個具體的類 然後, 書中有個寫法容易誤導人,即 將最終的調用的代碼,放在了 FtocStrategy 類中 其實應該放在另外的類中 因為,實際上是 ApplicationRunner 調用 FtocStrategy 而書中的寫法,很容易讓人以為是 FtocStrategy 調用的 ApplicationRunner 雖然,實際上是 FtocStrategy 需要使用 ApplicationRunner 中封裝的算法 但是,結合依賴倒置原則,ApplicationRunner 應該是調用方,而 FtocStrategy 是被調用方 綜上 從對象調用關系來看,ApplicationRunner 調用 FtocStrategy 從算法依賴關系來看,FtocStrategy 依賴了 ApplicationRunner 封裝的算法 在模板方法模式中,ApplicationRunner 被繼承,它的子類復制了它的代碼(延用了它的算法),實現功能 在策略模式中,ApplicationRunner 將算法和具體實現方法分離,它主動去調用實現了這些實現方法的對象,利用他們完成功能 從算法復用上看,ApplicationRunner 中的算法在兩種模式中,同樣被復用了 從調用關系上看,相對於模板方法模式,在策略模式中,ApplicationRunner 化被動為主動模板方法模式不符合 DIP,而策略模式符合 DIP
Facade(外觀模式)
個人理解:
將一套復雜的邏輯,封裝起來,只將需要關註的部分暴露給調用者
站在調用者的角度,那一套復雜的邏輯是不可見(也是不需要看見)的
調用者通過調用封裝的那一個接口去調用它背後的一套復雜邏輯
感覺 JDBC 就是使用了這一模式,但是查了一下,發現 JDBC 主要使用的是橋接模式,現在對這個模式不了解,以後再查查
Singleton (單例模式)
類和示例通常是一對多的關系
但是
對於某些特殊的類,它們只允許有一個實例,比如,工廠對象、管理器對象
如果這些類有多個實例,會引發嚴重的邏輯錯誤
此時,就需要用到單例模式
實現單例模式有三個要點:
1、私有化構造函數
2、一個私有的私立變量
3、公開、靜態的得到實例的方法(getInstance)
這樣,外部就只能通過 getInstance 方法才能獲取實例那個唯一的實例
敏捷軟件開發 第十三章~第十七章