熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

OO設計模式和設計原則

2022-06-13   來源: Java高級技術 

  作者 Cherami

   設計正在腐爛的征兆(Symptoms of Rotting Design)

  有四個主要的征兆告訴我們該軟件設計正在腐爛它們並不是互相獨立的而是互相關聯它們是過於僵硬過於脆弱不可重用性和粘滯性過高

   過於僵硬Rigidity Rigidity 致使軟件難以更改每一個改動都會造成一連串的互相依靠的模塊的改動項目經理不敢改動因為他永遠也不知道一個改動何時才能完成

   過於脆弱Fragility Fragility 致使當軟件改動時系統會在許多地方出錯並且錯誤經常會發生在概念上與改動的地方沒有聯系的模塊中這樣的軟件無法維護每一次維護都使軟件變得更加難以維護(惡性循環)

   不可重用性immobility immobility 致使我們不能重用在其它項目中或本項目中其它位置中的軟件工程師發現將他想重用的部分分離出來的工作量和風險太大足以抵消他重用的積極性因此軟件用重寫代替了重用

   粘滯性過高viscosity viscosity有兩種形式設計的viscosity和環境的viscosity當需要進行改動時工程師通常發現有不止一個方法可以達到目的但是這些方法中一些會保留原有的設計不變而另外一些則不會(也就是說這些人是hacks)一個設計如果使工程師作錯比作對容易得多那麼這個設計的viscosity 就會很高

  環境的viscosity高是指開發環境速度很慢且效率很低

   面向對象的類設計原則

   開放關閉原則The Open Closed Principle (OCP)

  A module should be open for extension but closed for modification一個模塊應該只在擴展的時候被打開(暴露模塊內部)在修改的時候是關閉的(模塊是黑盒子)

  在所有的面向對象設計原則中這一條最重要該原則是說我們應該能夠不用修改模塊的源代碼就能更改模塊的行為

   動態多態性(Dynamic Polymorphism)

   靜態多態性(Static Polymorphism)

  另外一種使用OCP的技術就是使用模板或范型如Listing LogOn函數不用修改代碼就可以擴展出多種類型的modem OCP的體系結構目標(Architectural Goals of the OCP)

  通過遵照OCP應用這些技術我們能創建不用更改內部代碼就可以被擴展的模塊這就是說在將來我們給模塊增添新功能是只要增加新的代碼而不用更改原先的代碼 頁使軟件完全符合OCP可能是很難的但即使只是部分符合OCP整個軟件的結構性能也會有很大的提高我們應該記住讓變化不要波及已經正常工作的代碼總是好的

   Liskov 替換原則The Liskov Substitution Principle(LSP)

  Subclasses should be substitutable for their base classes子類應該可以替換其基類

  如下圖所示Derived類應該能替換其Base類也就是說Base基類的一個用戶User如果被傳遞給一個Devrived類而不是Base類作為參數也能正常的工作

   依賴性倒置原則The Dependency Inversion Principle (DIP)

  Depend upon Abstractions Do not depend upon concretions依賴抽象不要依賴具體

  如果說OCP聲明了OO體系結構的目的DIP則闡述了其主要機制依賴性倒置的策略就是要依賴接口或抽象函數或抽象類而不是依賴於具體的函數和類這條原則就是支持組件設計COMCORBAEJB等等的背後力量

   依賴抽象Depending upon Abstractions

  實現該原則十分簡單設計中的每一個依賴都應該是接口抽象類不要依賴任何一個具體類

  顯然這樣的限制比較嚴峻但是我們應該盡可能的遵守這條原則原因很簡單具體的模塊變化太多抽象的則變化少得多而且抽象是鉸鏈在這些位置設計可以彎曲或者擴展而不用進行更改(OCP)

   接口隔離原則The Interface Segregation Principle (ISP)

  Many client specific interfaces are better than one general purpose interface多個和客戶相關的接口要好於一個通用接口

  ISP是另一條在底層支持組件如COM技術的原則沒有它組件和類的易用性和重用性都會大打折扣該原則的實質很簡單如果一個類有幾個使用者與其讓這個類載入所有使用者需要使用的所有方法還不如為每一個使用者創建一個特定的接口並讓該類分別實現這些接口

   包體系結構的原則Principles of Package Architecture

  類是必不可少的但對於組織一個設計來說還不夠粒度更大的包有助於此但是我們應該怎樣協調類和包之間的從屬關系?下面的三條原則都屬於包聚合原則能對我們有所幫助

   包聚合原則

   發布重用等價原則The Release Reuse Equivalency Principle (REP)

  重用的粒度就是發布的粒度The granule of reuse is the granule of release一個可重用的元件(組件一個類一組類等)只有在它們被某種發布(Release)系統管理以後才能被重用用戶不願意使用那些每次改動以後都要被強迫升級的元件因此即使開發者發布了可重用元件的新版本他也必須支持和維護舊版本這樣才有時間讓用戶熟悉新版本

  因此將什麼類放在一個包中的判斷標准之一就是重用並且因為包是發布的最小單元它們同樣也是重用的最小單元體系結構師應該將可重用的類都放在包中

   共同封閉原則The Common Closure Principle (CCP)

  一起變化的類放在一起Classes that change together belong together一個大的開發項目通常分割成很多網狀互聯的包管理測試和發布這些包的工作可不是微不足道的工作在任何一個發布的版本中如果改動的包數量越多重建測試和部署也就會越多因此我們應該盡量減少在產品的發布周期中被改動的包的數量這就要求我們將一起變化的類放在一起(同一個包)

   共同重用原則The Common Reuse Principle (CRP)

  不一起重用的類不應該放在一起Classes that arent reused together should not be grouped together對一個包的依賴就是對包裡面所有東西的依賴當一個包改變時這個包的所有使用者都必須驗證是否還能正常運行即使它們所用到的沒有任何改變也不行

  比如我們就經常遇到操作系統需要升級當開發商發布一個新版本以後我們的升級是遲早的問題因為開發商將會不支持舊版本即使我們對新版本沒有任何興趣我們也得升級

  如果把不一起使用的類放在一起同樣的事情我們也會遇到一個和我們無關的類的改變也產生包的一個新版本我們被強迫升級和驗證這個包是否影響正常的運行

   包聚合原則之間的張力Tension between the Package Cohesion Principles

  這三條原則實際上是互斥的它們不能被同時滿足因為每一條原則都只針對某一方面只對某一部分人有好處REP和CRP都想重用元件的人有好處CCP對維護人員有好處CCP使得包有盡可能大的趨勢(畢竟如果所有的類都屬於一個包那麼將只會有一個包變化)CRP盡量使得包更小

  幸運的是包並不是一成不變的實際上在開發過程中包的轉義和增刪都是很正常的在項目開發的早期軟件建築師建立包的結構體系此時CCP占主導地位維護只是輔助在體系結構穩定以後軟件建築師會對包結構進行重構此時盡可能的運用REP和CRP從而最大的方便重用元件的人員

   包耦合原則The Package Coupling Principles

  下面三條原則主要關心包之間的關系

   無依賴回路原則The Acyclic Dependencies Principle (ADP)

  包與包之間的依賴不能形成回路The dependencies between packages must not form cycles因為包是發布的粒度人們傾向於節省人力資源所以工程師們通常只編寫一個包而不是十幾個包這種傾向由於包聚合原則被放大後來人們就將相關的類組成一組

  因此工程師發現他們只會改動較少的幾個包一旦這些改動完成他們就可以發布他們改動的包但是在發布前他們必須進行測試為了測試他們必須編譯和連編他們的包所依賴的所有的包

   依賴穩定原則(Stable Dependencies PrincipleSDP)

  朝穩定的方向依賴Depend in the direction of stability雖然這條原則看起來很明顯但是關於這方面還是有很多需要說明的地方穩定性並不一定為大家所了解

  穩定性是什麼?站在一個硬幣上這穩定嗎?很可能你說不然而除非被打擾硬幣將保持那個位置很長時間硬幣沒有變化但是很難認為它是穩定的穩定性與需要改動所要做的工作量相關硬幣不穩定是因為只需要很小的工作量就能把它翻過來換個角度桌子就要穩定得多

  對於軟件這說明什麼?一個軟件包很難被改動受很多因素影響代碼大小復雜度透明度等等這些我們先不說可以肯定的一點是如果有很多其它的包依賴於一個軟件包那麼該軟件包就難以改動一個包如果被許多其它包依賴那麼該包是很穩定的因為這個包的任何一個改動都可能需要改動很多其它的包

   穩定抽象原則( Stable Abstractions Principle SAP)

  穩定的包應該是抽象包Stable packages should be abstract packages我們可以想象應用程序的包結構應該是一個互相聯系的包的集合其中不穩定的包在頂端穩定的包在底部所有的依賴方向朝下那些頂端的包是不穩定而且靈活的但那些底部的包就很難改動這就導致一個兩難局面我們想要將包設計為難以改動的嗎?

  明顯地難以改動的包越多我們整個軟件設計的靈活性就越差但是好像有一點希望解決這個問題位於依賴網絡最底部的高穩定性的包的確難以改動但是如果遵從OCP這樣的包並不難以擴展


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27445.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.