1。軟件的可維護性與可複用性 軟件的維護就是軟件的再生。系統的設計目標: 可擴展性,靈活性,可插入性。 可擴展性: 新的功能很容易集成到現有的系統中去,而不影響到系統的其餘模塊。 靈活性: 容許代碼修改平穩的發生。當修改一處時不至於影響到另外一處,這樣能夠縮小維護的代價。 可插入性: 容易用一個類替換已經存在的類。只要接口一致,更改實現類不影響類的使用者。 軟件的複用能夠提升軟件的生產率,而且恰當的複用能夠提升軟件的可維護性。 在之前,複用主要是代碼,函數,結構的複用,而如今複用主要針對類,接口,組件等等。可是複用並不必定會保證軟件的可維護性。不能由於代碼的重複等緣由就複用,須要根據具體的狀況來分析。要想經過複用來增強系統的可維護性,必須保證複用是支持可維護性的複用。 下面的一些設計原則能夠用來指導實踐。 2。開-閉 原則(OCP) 開閉原則是面向對象可複用的基石。它主要指:一個軟件實體對擴展開放,對修改關閉。在設計一個模塊的時候,應當是這個模塊在不被修改前提下被擴展。知足這個原則的系統在一個較高層次上實現了複用,也是易於維護的。 那如何才能知足開閉原則呢?抽象化是關鍵。要區分開抽象層和實現層。在一個軟件系統中,抽象層應該是相對穩定的,而實現層是能夠改變擴展的。 開閉原則也是對可變性的封裝原則。找到系統的可變因素,並將其封裝起來。把一種可變性封裝爲一個對象,那麼這種可變性的不一樣表象就是這個類的具體子類。 3。里氏代換原則(LSP) 里氏代換原則是繼承複用的基石:在任何父類出現的地方均可以用它的子類來替代。例如正方形和長方形。正方形是一種特殊的長方形。可是正方形卻不能做爲長方形的子類。因對長方形的操做並不必定能套用在正方形上。如:resize().若是正方形做爲長方形的子類的話,那麼就會出現不少問題。不符合里氏代換原則,正方形就不能做爲長方形的子類,應該把正方形和長方形都做爲四邊形的子類。在實際,設計類的階層繫結構時,這是一條很重要的原則。不該該做爲子類不能硬套。 4。依賴倒轉原則(DIP) 依賴倒轉原則是:要依賴於抽象,不要依賴於具體的實現。 爲何叫依賴倒轉原則呢? 在傳統的過程性系統中,高層的模塊依賴於低層次的模塊,抽象層次依賴於具體層次。這樣致使了底層的任何改變都會影響到上層。這樣的軟件系統沒有可維護性而言。 抽象層次應該不依賴於具體的實現細節,這樣才能保證系統的可複用性和可維護性,這也就是所謂的倒轉。 在實際中如何應用這一原則呢? 要針對藉口編程,而不針對實現編程。那麼當實現變化時,不會影響到其餘的地方。 在java中應當使用接口和抽象類來進行變量的類型聲明, 參數的類型聲明,方法的返回值類型,等等。好比: List list = new Linkedlist(); 以抽象的方式進行耦合是依賴倒轉原則的關鍵。 依照依賴倒轉原則,在系統中會出現大量的類,如抽象類和接口,由於它假定全部的具類都是有可能變化的。但實際上這也不老是正確的。有些具體類是很是穩定的,就不須要爲他發明一種新的類型。 5。 接口隔離原則(ISP) 使用多個專門的藉口老是比使用單一的總接口要好。一個接口應該僅表明一個角色,而不該該把全部的操做都封裝到一個接口當中。準確地劃 分角色和其所對應的接口,不該該把沒有關係的接口合併到一塊兒。 6。合成/聚合複用原則 聚合: 表示擁有或總體與部分的關係。 合成:更強的聚合關係。總體負責部分的生命週期,總體和部分是不可分的,部分是不能被共享的。好比孫悟空 ,他的四肢, 和他的武器。 悟空和四肢的關係就是合成,而和武器之間的關係就是聚合。 在面向對象中,有繼承和合成/聚合兩種基本服用方法。合成/聚合是將已有對象做爲本身的成員,新對象調用對象已有的功能。這有不少優勢: 1) 這種複用是黑箱操做,把成員對象的細節封裝起來。 2)這種複用能夠動態的改變,新對象能夠動態的引用其餘的同類對象。 繼承複用有以下的優勢和缺點。 1)容易實現。 2)繼承複用破壞了包裝,將超類的實現細節暴露給子類。 3)同時若是超類發生改變,子類也不得不跟着改變。 4)繼承是靜態的。 儘可能使用和成/聚合而不是繼承來實現複用。而區分這兩種關係,區分」Has-A」和「Is-A」的關係。能正確的區分二者,應該就能正確的使用 這兩種複用方式。例如:人和角色。一般使用繼承,能夠把每一個角色做爲人的子類。如學生,僱員,經理等。可是繼承是靜態的,一旦一我的有了一個角色後就不能再擁有其餘的角色。好比一我的是經理,但它也是僱員,也多是學生。這顯然是不合理的。應該採用合成/聚合複用則。實際上人與角色是「Has-A」而不是」 Is-a」的關係,而且只有當知足里氏代換原則的時候才能使「Is-a」的關係。 在java api中 Properties 繼承 Hashtable。Proterties具備了Hashtable的全部行爲。實際上,Properties根本就不是一種Hashtable.更嚴重是把Properties能夠向上轉型爲Hashtable,,繞過Properties接口,調用Hashtable的方法來對Properties操做,會致使Properties的內部矛和崩潰。他們之間能夠是「Has-a」,但不能是」Is-a」的關係。在實際中,決不能由於代碼和功能上的複用而濫用繼承,使用繼承時必定要知足里氏代換原則。 7。迪米特法則(LoD) 迪米特法則: 一個對象應當對其餘對象儘量少的瞭解。如下是一些表述: 1) 只和你直接的朋友通訊 2) 不要和陌生人講話。 3)每個軟件單位都對其餘單位只有最少的知識。 其目的就是下降各個單元的耦合,提升系統的可維護性。在模塊之間,其通訊應該只經過彼此的API來通訊,而不理會模塊的內部工做原理。它可使各個模塊耦合程度降到最低,促進軟件的複用。 本文轉自程式先鋒網站 www.javabiz.cn