在Robert C. Martin(Bob大叔)的
《敏捷軟件開發:原則、模式與實踐》(Agile Software Development: Principles, Patterns, and Practices)
一書中,他提出了一些用于設計組件(或包)的原則。傳統的面向對象設計原則,例如SOLID、CARP、LoD等主要關注類的設計,而下面要介紹的這些原則主要用于設計組件和包的結構,一共包括六個原則:前面三個關注組件的
內聚性(Cohesion)
,用于指導我們如何將類組包;后面三個關注組件的
耦合性(Coupling)
,幫助我們確定組件之間的相互關系。簡單來說,組件(或包)的設計也要做到“
高內聚,低耦合
”。Sunny認為,有些原則描述的是一種理想狀況,在實際使用時更多的是盡量
趨向于
這些原則,通常很難做到百分之百滿足這些原則,
。
組件內聚性原則:粒度 (Principles of Component Cohesion: Granularity)
組件的內聚性原則幫助開發者決定 如何將類劃分到組件中 。這些原則取決于這樣的事實: 至少已經存在一些類并且它們之間的相互關系也得以確定 。因此,這些原則根據自底向上的觀點對類進行劃分,先分析類以及關系,再逐步對類進行組織。
重用-發布等價原則(
The Reuse/Release Equivalence Principle
, REP)
?The granule of reuse is the granule of release.
重用的粒度就是發布的粒度。
在實際開發中,我們的重用粒度通常不是類一級的,而是組件一級的,這里所說的組件可以是Java中的jar,也可以是DLL或者共享庫等。REP要求我們保持組件的
重用粒度(granule of reuse)
和組件的
發布粒度(granule of release)
一致,何謂重用、何謂發布我想大家應該都懂,
。由于重用是在組件這一級,因此可重用的組件中必須包含可重用的類,這些可重用的類以組件的方式發布給用戶使用。REP要求我們從重用的角度去考慮一個組件的內容,一個組件中的類要么都可以重用,要么都不是可重用的(Either all the classes in a component are reusable, or none of them are.)。例如在一個基于Model 2的Java EE項目中,我們將所有的DAO類打包為一個jar,目的是在其他基于相同數據庫的項目中能夠重用所有的DAO類,在這個DAO組件中就不應該包含任何控制層(Servlet)或者表示層(JSP等)相關的類,因為這些類不能同時被重用。
此外,在實施REP時,與面向對象設計原則中的SRP(單一職責原則)類似,在一個組件中不應該包含太多不同類型的類,不要把一些完全不相干的類放在一個組件中,這樣會導致組件的職責過重,增加修改和發布的頻率。因此,我們應該讓一個組件中的所有類對于同一類用戶或者面向同一場景是可以重用的,不應該讓組件中的一部分類對用戶而言有用而其他類不適用。
簡而言之,REP要求我們從復用的角度來設計組件, 讓一個組件中所有的類都能夠一起被復用,不存在不能復用的類,也不存在只有在另一種場合下才能夠被復用的類。復用的粒度即發布組件的粒度。
共同重用原則(The Common Reuse Principle, CRP)
?
The classes in a component are reused together. If you reuse one of the classes in a component, you reuse them all.
一個組件中的類需一起被重用。 如果你重用了組件中的一個類,那么就要重用其中所有的類。
CRP與之前的REP通常會一起出現,同一個組件中的類作為一個整體被復用,而不是只復用其中的某一個或幾個類。我個人覺得,CRP是一種理想情況,它有利于降低組件之間的耦合度,但是實現起來有一定的難度,對于一個類稍微多一點的組件,很難同時復用其中所有的類,大部分情況下都只是使用其中的部分類,
。我們需要做的是,
盡量讓這些類位于同一個組件中,減少與客戶端程序交互的組件數量,降低系統耦合度。
CRP告訴我們需要將哪些類放在同一個組件中, 在略為復雜一點的系統中,類很少會孤立的重用。例如,有時候需要將一個具體類和它的抽象層一起重用,需要將一個聚合類和它的迭代器一起重用,需要將工廠類和產品類一起重用,此時,最好將它們設計在同一個組件中。如果將它們分離開,放在兩個不同的組件里,勢必會在一些組件之間增加依賴關系,被依賴方的組件發生修改和重新發布時,依賴方的組件也需要重新驗證和發布,導致維護和升級工作量增加。
此外,如果一個組件中類太多,只要該組件中一個類發生改變重新發布時,所有依賴這個組件的客戶類都應該進行測試驗證,看是否引入bug,即使發生修改的類與大部分客戶類都沒有任何關系,這樣一來,導致測試工作量也會有所增加,需要進行大量不必要的重新驗證和重新發行,費時費力。
CRP更多是告訴我們 沒有緊密聯系的類不應該放在一個組件中,在一個組件中應該只包含那些需要一起被重用的類。
共同封閉原則(The Common Closure Principle, CCP)
?
The classes in a component should be closed together against the same kinds of changes. A change that affects a component affects all the classes in that component and no other components.
一個組件中的所有類對于同一種類型的變化應該是共同封閉的。 一個變化若對一個組件產生影響,則將影響該組件中所有的類,而對其他組件不造成影響。
這個原則實際上就是組件的單一職責原則(SRP),也就是說 一個組件不應該包含多個引起它發生改變的原因 。在大多數應用中,可維護性比可重用性更重要。如果一個應用中的代碼需要發生修改,盡量讓這種修改都集中在一個組件中,而不是分散在多個組件中,例如更換數據庫,只需要修改或更換與數據庫操作有關的組件;更換視圖層的界面,只需修改或更換新的界面組件。如果所有的更改集中在一個單一的組件中,我們只需重新發布那一個組件即可,這個組件通常也不會很巨大,易于維護和重用。如果將這些更改分散在多個組件中,將增加軟件發布、驗證和維護工作量。
實施CCP要求我們識別出那些關系很緊密的類,盡量將這些類封裝到同一個組件中,避免后期需要修改多個組件。
CCP要求我們 把對某一類型改變 (例如更換數據庫) 敏感的類組織到同一個組件中,當需求中一個變更到來時,可以將變化限制在最少數量的組件中 。
總結
在考慮如何將類組織到組件中時,需要充分考慮組件的可復用性和可維護性, 一起被重用的類盡量放到一個組件中,一起受影響需修改的類盡量放到一個組件中 。我們還要注意,隨著項目的開展,組件的組成可能會隨著時間而演化,需要相應作一些調整。我們在進行初始設計時需要盡量考慮全面,降低組件的修改工作量!
【作者:劉偉 http://blog.csdn.net/lovelion 】
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
