層次分解
您永遠不應該立即開始為您的應用程序編寫類。首先需要對其進行設計。設計應該以深思熟慮的架構結束。要獲得此架構,您需要始終如一地分解系統。
分解必須分層進行——首先,系統被分成大的功能模塊/子系統,以最一般的形式描述其操作。然後對生成的模塊進行更詳細的分析,並將其劃分為子模塊或對象。
在選擇對象之前,將系統分成基本的語義塊,至少在心理上是這樣。在小型應用程序中,這通常很容易做到:幾個級別的層次結構就足夠了,因為系統首先分為子系統/包,而包又分為類。
![層次分解](https://cdn.codegym.cc/images/article/d5e9aa2b-5783-430f-b5b5-1832bc33c540/800.jpeg)
這個想法並不像看起來那麼微不足道。例如,模型-視圖-控制器(MVC)這種常見的“架構模式”的本質是什麼?
這一切都是關於將表示與業務邏輯分開。首先,任何用戶應用程序都分為兩個模塊——一個負責實現業務邏輯本身(模型),第二個負責與用戶交互(用戶界面或視圖)。
然後事實證明,模塊必須以某種方式交互,為此他們添加了一個控制器,其任務是管理模塊的交互。同樣在移動(經典)版本的MVC中,加入了Observer模式,使得View可以接收來自模型的事件,實時改變顯示的數據。
典型的頂級模塊,作為系統第一次劃分為最大組件的結果,準確地說是:
- 商業邏輯;
- 用戶界面;
- 數據庫;
- 消息系統;
- 對象容器。
第一次拆分通常將整個應用程序拆分為 2-7(最多 10 個部分)。如果我們把它分解成更多的部分,那麼就會有對它們進行分組的願望,我們又會得到 2-7 個頂層模塊。
功能分解
最好根據系統解決的任務來劃分模塊/子系統。主要任務分為其組成的子任務,這些子任務可以相互獨立地自主解決/執行。
每個模塊都應該負責解決一些子任務並執行其相應的功能。除了功能目的之外,模塊的特徵還在於它執行其功能所必需的一組數據,即:
模塊 = 函數 +執行它所需的數據。
如果正確地分解成模塊,那麼與其他模塊(負責其他功能)的交互將是最小的。它可能是,但它的缺失對你的模塊來說並不重要。
模塊不是任意一段代碼,而是一個單獨的具有功能意義和完整的程序單元(子例程),它為特定任務提供解決方案,理想情況下,可以獨立工作或在另一個環境中工作並被重用。模塊應該是一種“能夠在行為和發展上相對獨立的完整性”。(克里斯托弗·亞歷山大)
因此,有效的分解首先基於對系統功能和執行這些功能所需數據的分析。這種情況下的函數不是類函數和模塊,因為它們不是對象。如果一個模塊中只有幾個類,那麼你就做得太過了。
強連接和弱連接
非常重要的是不要過度模塊化。如果你給一個初學者一個整體的Spring應用,讓他把它分解成模塊,那麼他會把每個Spring Bean拿出來放到一個單獨的模塊中,並認為他的工作完成了。但事實並非如此。
分解質量的主要標準是模塊如何專注於解決它們的任務並且是獨立的。
這通常表述如下:“作為分解結果獲得的模塊應該在內部最大程度地共軛(高內部凝聚力)並且最小程度地相互連接(低外部耦合)。”
High Cohesion,模塊內部的高內聚或“內聚”,表示該模塊專注於解決一個狹義的問題,而不是從事執行異構功能或不相關的職責。
內聚性表徵了模塊執行的任務之間相互關聯的程度。
高內聚的結果是單一責任原則——五個 SOLID 原則中的第一個,根據該原則,任何對象/模塊都應該只有一個責任,並且改變它的理由不應該超過一個。
Low Coupling,鬆散耦合,是指系統劃分成的模塊之間應該盡可能獨立或鬆散耦合。他們應該能夠互動,但同時盡可能少地了解彼此。
每個模塊都不需要知道另一個模塊是如何工作的,它是用什麼語言編寫的,以及它是如何工作的。通常,為了組織這些模塊的交互,使用特定的容器,將這些模塊加載到其中。
通過適當的設計,如果您更改一個模塊,則不必編輯其他模塊,或者這些更改將是最小的。耦合越松,就越容易編寫/理解/擴展/修復程序。
人們認為,設計良好的模塊應該具有以下特性:
- 功能完整性和完備性——每個模塊實現一個功能,但實現得好、完整,模塊獨立執行全套操作來實現其功能。
- 一進一出——在輸入處,程序模塊接收到一組初始數據,進行有意義的處理並返回一組結果數據,即實現了標準的IPO原則——輸入-\u003e過程-\u003e輸出。
- 邏輯獨立性——程序模塊的工作結果只依賴於初始數據,而不依賴於其他模塊的工作。
- 與其他模塊的信息鏈接較弱——如果可能,應盡量減少模塊之間的信息交換。
初學者很難理解如何進一步減少模塊的連通性。這種知識部分來自於經驗,部分來自閱讀智能書籍之後。但最好分析現有應用程序的架構。
組合而不是繼承
勝任分解是一門藝術,對大多數程序員來說都是一項艱鉅的任務。簡單在這裡具有欺騙性,錯誤代價高昂。
![](https://cdn.codegym.cc/images/article/d7e785ed-e16d-4354-883c-0ad83327512a/512.jpeg)
恰好專用模塊之間強耦合,無法獨立開發。或者不清楚他們各自負責什麼功能。如果您遇到類似的問題,那麼很可能是模塊劃分不正確。
應該始終清楚每個模塊扮演什麼角色。正確完成分解的最可靠標準是模塊是否是獨立且有價值的子例程,可以與應用程序的其餘部分隔離使用(因此可以重用)。
分解系統時,最好通過問自己以下問題來檢查其質量:“每個模塊執行什麼任務?”、“測試模塊有多容易?”、“是否可以單獨使用這些模塊還是在另一個環境?影響他人?
您需要盡量保持模塊的自主性。如前所述,這是正確分解的關鍵參數。因此,必須以模塊之間最初弱依賴的方式進行。如果你成功了,那你就很棒了。
如果不是,那麼這裡也不會丟失所有內容。有許多特殊的技術和模式可以讓您進一步減少和削弱子系統之間的聯繫。例如,在 MVC 的情況下,觀察者模式用於此目的,但其他解決方案也是可能的。
可以說,解耦技術構成了主要的“架構師工具包”。只需要明白,我們說的是所有的子系統,需要弱化層次結構各個層級的聯繫,即不僅是類之間,還包括各個層級模塊之間的聯繫。