用消息傳遞代替直接依賴
有時一個模塊只需要通知其他人它發生了一些事件/變化,而這些信息以後發生什麼並不重要。
在這種情況下,模塊之間根本不需要“相互了解”,即包含直接鏈接並直接交互,但只需交換消息(messages)或事件(events)就足夠了。
有時似乎通過消息傳遞的模塊通信比直接依賴要弱得多。事實上,因為沒有調用方法,所以沒有關於類的信息。但這只不過是一種錯覺。
邏輯開始與消息類型、它們的參數和傳輸的數據相關聯,而不是方法名稱。這些模塊的連接性被抹黑了。
它曾經是這樣的:我們調用方法 - 有連接,我們不調用方法 - 沒有連接。現在假設模塊 A 開始在其消息中發送略有不同的數據。同時,依賴於這些消息的所有模塊都將無法正常工作。
假設之前,在添加新用戶時,授權模塊發送消息USER_ADDED,更新後,嘗試註冊時開始發送此消息,並在參數中額外指示註冊成功與否。
因此,非常勝任地實現消息機制是非常重要的。為此有各種模板。
觀察員。它用於一對多依賴的情況,當許多模塊依賴於其中一個的狀態時——主模塊。它使用郵件機制,這意味著主模塊簡單地向它的所有訂閱者發送相同的消息,並且對此信息感興趣的模塊實現“訂閱者”接口並訂閱郵件列表。
這種方法廣泛用於具有用戶界面的系統中,允許應用程序(模型)的核心保持獨立,同時通知其關聯界面某些內容已更改並需要更新。
這裡的消息格式在操作系統級別是標準化的,其開發人員必須注意向後兼容性和良好的文檔。
通過消息分發來組織交互有一個額外的“好處”——“訂閱者”對“發布”(即發送)消息的可選存在。像這樣設計良好的系統允許隨時添加/刪除模塊。
消息總線
您可以組織消息交換並為此以不同的方式使用調解器模式。
當模塊之間存在多對多依賴關係時使用它。中介者作為模塊間通信的中介,充當通信中心,消除了模塊之間顯式引用的需要。
因此,模塊之間的交互(“all with all”)被模塊之間僅與中介的交互(“one with all”)所取代。據說中介者封裝了多個模塊之間的交互。
這就是所謂的智能中介。正是在那裡,開發人員最常開始添加他們的拐杖,這通過打開/關閉接收某些消息來影響各個模塊的行為。
一個典型的現實例子是機場交通管制。來自飛機的所有消息都會發送到控制器的控制塔,而不是直接在飛機之間發送。控制器已經決定哪些飛機可以起飛或降落,然後向飛機發送消息。
重要的!模塊不僅可以相互發送簡單的消息,還可以發送命令對象。這種交互由命令模板描述。底線是將執行特定操作的請求封裝為單獨的對象。
事實上,這個對象包含一個單獨的execute()方法,然後它允許您將此操作作為參數傳遞給其他模塊以執行,並且通常可以使用可以對普通對象執行的命令對象執行任何操作。
得墨忒耳法則
Demeter 法則禁止使用隱式依賴:“如果對象 A 可以訪問對象 B,對象 B 可以訪問對象 C,則對象 A 不能直接訪問對象 C。”
這意味著代碼中的所有依賴項都必須是“明確的”——類/模塊只能在其工作中使用“它們的依賴項”,而不應通過它們爬升到其他依賴項。一個很好的例子是三層架構。接口層應該與邏輯層一起工作,但不應該直接與數據庫層交互。
簡而言之,這條原則也可以這樣表述:“只與最直接的朋友互動,不要與朋友的朋友互動。” 這會降低代碼的連貫性,同時提高其設計的可見性和透明度。
Demeter 法則實現了已經提到的“最少知識原則”,這是鬆散耦合的基礎,包括一個對象/模塊應該知道盡可能少的關於其他對象/模塊的結構和屬性的細節,以及一般的任何東西,包括它自己的組件。
生活中的一個比喻:如果你想讓狗跑,指揮它的爪子是愚蠢的,不如把命令交給狗,它會自己處理自己的爪子。
組合而不是繼承
這是一個非常大且有趣的話題,至少值得單獨講一講。在達成共識之前,互聯網上關於這個話題的很多副本都被打破了——我們使用繼承到最低限度,組合——到最大。
關鍵是繼承實際上提供了類之間最強的聯繫,所以應該避免。Herb Sutter 的文章“ Prefer Composition Over Inheritance ”中詳細介紹了這個主題。
當您開始學習設計模式時,您會遇到一大堆控制對象創建或其內部結構的模式。順便說一句,在這種情況下,我建議您注意來自遊戲的委託/委託模式和組件模式。
我們稍後會詳細討論模式。
GO TO FULL VERSION