《敏捷軟件開發》讀書筆記(3)

《敏捷軟件開發》讀書筆記(3)

書中設計模式的彙總

命令類模式,分離執行和定義

CMD模式

其實是事件-事務綁定的模型:

  1. 可以用事件驅動,只要收到事件,執行綁定到事件對應的CMD對象.do方法就行,對於真正執行的事情無感知。解除了系統的邏輯互聯關係和實際連接關係的設備之間的耦合。
  2. 事務型操作,把驗證和執行分離,由執行框架完成驗證和執行操作。解除了獲取數據、驗證數據、執行數據操作這種空間耦合,同時也可以在執行時間上進行解耦。擴展可以增加undo接口,系統把CMD對象壓入堆棧,在進行回退的時候調用undo。

整體上就是把程序算法或者業務邏輯,和程序的實際控制執行解耦,有點像函數式編程。

ACTIVE OBJECT模式

這部分沒看懂,似乎是多線程任務執行引擎,可以把CMD對象放回到引擎列表中。這種類型的線程任務是RTC線程。

複用算法,分離業務邏輯的模式

TEMPLATE METHOD模式

把算法的控制和邏輯分離,通用算法封裝到基類,不需要理解的邏輯部分交給子類實現,比如冒泡排序。(其實不一定用繼承,可以用組合),注意防止濫用。

STRATEGY模式

相比TEMPLATE METHOD,更好的解除了具體實現和算法的耦合,使用接口+組合,而不是繼承,能提高具體實現的複用性,優先使用。

統一對外接口,隱藏策略的模式

FACADE模式

封裝組件對外的策略和約束,要求外部系統統一通過某個簡單且特定的接口訪問,對外呈現唯一的代理接口。

MEDIATOR模式

也是策略的一種,但是是隱蔽的,比如監聽文本變化並且對其他列表進行操作,文本框本身是不感知到策略的存在的。

單例的兩種模式

SINGLETON模式

單例對象,是非常常用的模式,好處:跨平臺、適用於任何類、可以派生創建、延遲求值。代價:無法指定銷燬機制、不能繼承、效率問題、不透明性。強調結構上的單一。

MONOSTATE模式

對使用者而言是多個實例,但是內部操作的是同一個空間。好處:透明、可派生、多態。代價:不可轉換、效率、內存、平臺侷限。強調行爲上的單一。如果希望對使用者透明,或者希望用單一對象的多態對象,比如狀態機,可以選用。

NULL模式,避免判空編碼

NULL OBJECT模式

用空實現代替返回null指針,避免判空的同時,也明確了對象不存在時的行爲。

FACTORY模式

使用這個模式,可以滿足DIP原則,避免依賴實現類,不要直接new,可以用Factory來完成創建。但是這會讓調用方對工廠類產生依賴,一旦創建類型增加,就會被迫重新編譯部署,可以用字符串映射的方式犧牲一點類型安全性。好處是可以無縫替換實現,讓調用者依賴抽象。可以解決包之間耦合具體實現的問題。

COMPOSITE模式

如果對一組對象的使用行爲完全一致,那麼可以創建一個包含該對象列表的對象,讓客戶方還是認爲是一對一的結構關係,把行爲變成一對多的。要注意只有使用對象是完全一致的方式才具備轉換的可能性。

OBSERVER模式

又是個常用的模式了,可以滿足設計的OCP原則。這裏得到新的理解是分爲“推”模式和“拉”模式。推即爲數據更新的時候,主動把數據推送給觀察者,拉即爲數據更新的時候,只發送更新通知,讓觀察者主動去查。拉模式的關鍵問題在於,不知道數據源發生了什麼樣的變更,不過觀察者模型的對象簡單,複用程度高。對於如何選擇,如果被觀察的對象簡單,適合用拉模式,如果很複雜,可以用推模式,告訴觀察者什麼發生了變化。

幾種橋接解耦的模式

ABSTRACT SERVER模式

解決使用方依賴具體實現方實現類的問題。客戶調用提供服務方,如果要避免依賴具體實現,滿足DIP原則,那麼可以定一個接口,由客戶方調用接口,服務方實現接口。而且接口是屬於客戶方定義的。

ADAPTER模式

如果以上的ABSTRACT SERVER模式,服務方無法實現接口或者是第三方的,那就在中間加一個ADAPTER實現接口,再調用真正的服務方。(以上是對象形式的,還有一種類形式的ADAPTER,沒太理解)考慮書中282頁的調制解調器的例子,可以用ADAPTER隔離真正客戶方不關心的部分,在ADAPTER裏處理對接已有系統的兼容轉換邏輯。

BRIDGE模式

略顯複雜,在遇到類層次自由度多的時候,可以把結構分開,用橋結合到一起。不會影響到使用方,而且把不同實現策略的服務方隔離開了,最終還是解決隔離的問題,還需要再理解一下。

故障隔離相關的模式

以下模式是爲了解決軟件中處理故障的同時,任然保持程序關注於本身要解決的問題,不過要注意不要在一開始就預測需要的模式,建議先用Facade模式,再在必要時重構。

PROXY模式

需要用到數據庫的地方,讓數據庫操作的類,實現領域接口類一模一樣的方法,作爲Proxy類,然後數據庫實現類去依賴領域實現類,完成數據庫到實體的轉換,再完成接口調用。這樣把業務邏輯保持封裝在領域模型中,任何數據庫的更改,不會影響到領域模型。(不明白的點是,調用方要直接創建數據庫的代理實現類,修改的時候其實是會影響調用者的吧?另外,代理如何做到第三方的依賴反轉的?)注意代理是非常重型的模式,需要謹慎使用。

STAIRWAY TO HEAVEN模式

和上面的PROXY類似,但不是用委託調用領域類,而是用繼承實現,這對語言有要求,需要支持多重繼承。

可以用於數據庫的其他模式

EXTENSION OBJECT模式

由領域類直接返回擴展對象如Database擴展,然後直接調用擴展對象進行數據庫讀寫。

VISTOR模式

把寫入動作交給Vistor,由具體對象的accept方法執行結構化寫入(Android的序列化就是這樣的模式)

Decorator

裝飾一個業務對象並賦予read和write方法;或者可以裝飾一個知道如何讀寫自身的數據對象並賦予業務規則

Facade

直接對外提供readXxx/writeXxx方法,會有些耦合。

解決類層次的擴展問題的模式VISITOR

解決的問題:需要向類層次結構中增加新的方法,但是增加起來會很費勁或者會破壞設計

VISITOR模式

增加一個訪問者的角色,用visit的方式去調用被訪問者相關的方法,可以滿足開閉原則,對現有系統影響最小。核心是雙重分發,第一次是accept方法的多態分發,分發到要執行方法所屬的類型,第二次是visit的分發,分發到要執行的具體函數或者邏輯。對於被訪問者每一個實現類,訪問者都有一個對應的方法,被訪問者在accept裏調用訪問者.visit(this)。書中利用Model的例子,解釋瞭如何構建VISITOR模式。如同一個功能矩陣,每個點都由對應的實現。但是這裏有個問題,visitor依賴實現類,但是被訪問者依賴這個訪問者,會存在循環依賴。

ACYCLIC VISITOR模式

爲了解決以上循環依賴的問題,可以將visitor變成退化的,耦合具體訪問者實現的部分,提供一個接口出來給訪問者調用,完成派生類到接口的180度旋轉。但這樣的方式更復雜,而且轉型耗時無法估計,對強實時系統不適用,對增量編譯比較重要的系統適用。這個模式如同一個稀疏矩陣,可以裁剪某些不必要的功能。

VISITOR模式還可以用於生成報表,而不打破任何數據的數據結構。通常在程序中存在許多種不同方式進行解釋或者使用多數據結構時,就可以使用。可以讓每個訪問者所使用的數據結構都獨立於他的用途,並且訪問者還可以隨時創建新的,可以隨意配置部署,這太棒了。

DECORATOR裝飾器模式

再次考慮Model的情況,如何在不修改已有類行爲的情況下,增加撥號時的處理?解決方案是創建一個新的裝飾類實現Model接口,並且傳入已有的Model對象,在dial方法之前之後進行其他處理,將真正的撥號委託給原Model對象,完成了功能的增強又不修改原代碼,這也體現了面向接口編程的好處。如果有很多裝飾類,可以創建一個基礎裝飾類,把通用的委託代碼放在裏面,由具體的裝飾類繼承實現,複寫需要委託的方法部分即可。

EXTENSION OBJECT模式

類層次中每一層根據一個KEY來管理擴展對象,由擴展對象進行擴展功能補充,比如序列化爲XML或者CSV擴展。並且擴展對象可以在創建時進行指定,或者動態添加刪除。

總結:以上三種模式,有助於保持OCP,在不修改原有代碼的情況下增加行爲和能力,也增強了SRP原則。

STATE設計模式

有限狀態自動機,至少由4部分組成:起始狀態、觸發遷移的事件、終止狀態、要執行的動作。可以藉助以下兩種表達方式,這兩種表示方式,可以幫助我們分析場景不要遺漏,比如每個狀態遇到每種事件多時候,分別應該做什麼樣的處理。:

STD狀態遷移圖

[起始狀態]->觸發事件/執行動作–>[終止狀態]

STT狀態遷移表

起始狀態 觸發事件 終止狀態 執行動作

如何實現STATE模式

嵌套switch/case語句

處理每個狀態下,收到每種事件後,相應的處理。另外,action的抽象,使得狀態機的邏輯和執行的具體操作實現之間解耦。這種方式的好處,對於簡單的狀態機實現很清晰,但是對於大型的FSM來說就會是噩夢。另外一個代價是,邏輯和實現代碼不容易被很好的分離。

解釋遷移表

創建一個狀態遷移表,由一個遷移引擎來進行事件匹配遷移和調用相應動作,修改狀態。這種好處是,構建遷移表的代碼讀起來就像是一個規範的遷移表,狀態機的邏輯全部集中在一個地方,並且不會被污染。另一個好處是遷移表可以動態部署,實現業務邏輯的熱補丁。代價主要是速度,解釋遷移表需要時間,而且解釋引擎會比較複雜。

STATE模式的結構實現
  1. 定義一個State類,提供的接口是遷移事件。
  2. 由具體的State實現類處理每個遷移事件,調用上下文類的動作和狀態遷移方法。
  3. STATE模式是一種STRATEGY的一種特例,派生類會回指上下文類。

用這種實現徹底分離了狀態機的邏輯和動作,而且可以輕易擴展狀態、修改動作的實現,且非常高效。代價主要是編寫狀態派生類會比較麻木,另外邏輯是分散的,無法在一個文件裏就看清整個邏輯。

SMC 狀態機編譯器

作者利用工具,設計了一個描述問題,把FSM的描述文件,自動生成一組實現狀態機的類。

可以在哪些地方使用狀態機

GUI中的高層策略

比如登錄界面的業務邏輯,可以用狀態機來表達(回想項目中,初始化路由過程也可以通過狀態機表達)

GUI交互控制器

GUI上的實現,接收用戶輸入事件作爲狀態遷移事件,驅動屏幕繪製相關的動作執行和狀態遷移。

分佈式處理

比如TCP數據傳輸的端口狀態。

總結:FSM沒有被充分使用,在許多情況中,使用FSM會有助於創建更清楚、簡單、靈活以及準確多代碼。(即使不用狀態機實現,用狀態機分析思路也有助於做出可靠的程序)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章