當前位置:編程學習大全網 - 源碼下載 - OO設計模式和設計原則

OO設計模式和設計原則

 作者 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 Polymorphi *** )

  靜態多態性(Static Polymorphi *** )

 另外壹種使用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則闡述了其主要機制 依賴性倒置的策略就是要依賴接口 或抽象函數 或抽象類 而不是依賴於具體的函數和類 這條原則就是支持組件設計 CORBA EJB等等的背後力量

  依賴抽象Depending upon Abstractions

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

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

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

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

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

  包體系結構的原則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 aren t reused together should not be grouped together 對壹個包的依賴就是對包裏面所有東西的依賴 當壹個包改變時 這個包的所有使用者都必須驗證是否還能正常運行 即使它們所用到的沒有任何改變也不行

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

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

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

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

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

  包耦合原則The Package Coupling Principles

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

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

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

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

  依賴穩定原則(Stable Dependencies Principle SDP)

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

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

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

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

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

lishixinzhi/Article/program/Java/gj/201311/27445

  • 上一篇:微信公眾號圖文模板如何復制?怎麽把微信公眾號文章復制到另壹個公眾號中
  • 下一篇:網頁內圖片連接問題
  • copyright 2024編程學習大全網