軟件設計的六大原則

開閉原則

對擴展開放,對修改關閉,即:在不改變原代碼的狀況下進行擴展。編程

任何軟件都須要面臨一個很重要的問題,即它們的需求會隨時間的推移而發生變化。當軟件系統須要面對新的需求時,咱們應該儘可能保證系統的設計框架是穩定的。若是一個軟件設計符合開閉原則,那麼能夠很是方便地對系統進行擴展,並且在擴展時無須修改現有代碼,使得軟件系統在擁有適應性和靈活性的同時具有較好的穩定性和延續性。隨着軟件規模愈來愈大,軟件壽命愈來愈長,軟件維護成本愈來愈高,設計知足開閉原則的軟件系統也變得愈來愈重要。框架

爲了知足開閉原則,須要對系統進行抽象化設計,抽象化是開閉原則的關鍵。在Java、C#等編程語言中,能夠爲系統定義一個相對穩定的抽象層,而將不一樣的實現行爲移至具體的實現層中完成。在不少面向對象編程語言中都提供了接口、抽象類等機制,能夠經過它們定義系統的抽象層,再經過具體類來進行擴展。若是須要修改系統的行爲,無須對抽象層進行任何改動,只須要增長新的具體類來實現新的業務功能便可,實如今不修改已有代碼的基礎上擴展系統的功能,達到開閉原則的要求。編程語言

優勢:實踐開閉原則的優勢在於能夠在不改動原有代碼的前提下給程序擴展功能。增長了程序的可擴展性,同時也下降了程序的維護成本。函數

體悟:開閉原則應當和單一職責原則聯繫緊密,只有一個類的職責足夠少,才能作到儘量少的耦合,以達到在後期的擴展中,不會改變到原有的類學習

里氏替換原則

全部引用基類對象的地方可以透明地使用其子類的對象設計

里氏代換原則告訴咱們,在軟件中將一個基類對象替換成它的子類對象,程序將不會產生任何錯誤和異常,反過來則不成立,若是一個軟件實體使用的是一個子類對象的話,那麼它不必定可以使用基類對象。例如:我喜歡動物,那我必定喜歡狗,由於狗是動物的子類。可是我喜歡狗,不能據此判定我喜歡動物,由於我並不喜歡老鼠,雖然它也是動物。code

例若有兩個類,一個類爲BaseClass,另外一個是SubClass類,而且SubClass類是BaseClass類的子類,那麼一個方法若是能夠接受一個BaseClass類型的基類對象base的話,如:method1(base),那麼它必然能夠接受一個BaseClass類型的子類對象submethod1(sub)可以正常運行。反過來的代換不成立,如一個方法method2接受BaseClass類型的子類對象sub爲參數:method2(sub),那麼通常而言不能夠有method2(base),除非是重載方法。對象

里氏代換原則是實現開閉原則的重要方式之一,因爲使用基類對象的地方均可以使用子類對象,所以在程序中儘可能使用基類類型來對對象進行定義,而在運行時再肯定其子類類型,用子類對象來替換父類對象。繼承

優勢:能夠檢驗繼承使用的正確性,約束繼承在使用上的泛濫。接口

體悟: 這個說法相似面向對象中的多態,在使用中定義基類避免出現類型錯誤,在運行時在肯定其具體子類類型

依賴倒置原則

抽象不該該依賴於具體類,具體類應當依賴於抽象。換言之,要針對接口編程,而不是針對實現編程。

依賴倒轉原則要求咱們在程序代碼中傳遞參數時或在關聯關係中,儘可能引用層次高的抽象層類,即便用接口和抽象類進行變量類型聲明、參數類型聲明、方法返回類型聲明,以及數據類型的轉換等,而不要用具體類來作這些事情。爲了確保該原則的應用,一個具體類應當只實現接口或抽象類中聲明過的方法,而不要給出多餘的方法,不然將沒法調用到在子類中增長的新方法。

在引入抽象層後,系統將具備很好的靈活性,在程序中儘可能使用抽象層進行編程,而將具體類寫在配置文件中,這樣一來,若是系統行爲發生變化,只須要對抽象層進行擴展,並修改配置文件,而無須修改原有系統的源代碼,在不修改的狀況下來擴展系統的功能,知足開閉原則的要求。

優勢:經過抽象來搭建框架,創建類和類的關聯,以減小類間的耦合性。並且以抽象搭建的系統要比以具體實現搭建的系統更加穩定,擴展性更高,同時也便於維護。

體悟:利用抽象類下降類與類之間的耦合,用抽象類進行類之間的聯繫,改變某一類只須要改變抽象的接口,或者某一類的實現便可,不會改變原有類,利於擴展也利於維護。

單一職責原則

一個類只負責一個功能領域中的相應職責,或者能夠定義爲:就一個類而言,應該只有一個引發它變化的緣由。

單一職責原則告訴咱們:一個類不能太「累」!在軟件系統中,一個類(大到模塊,小到方法)承擔的職責越多,它被複用的可能性就越小,並且一個類承擔的職責過多,就至關於將這些職責耦合在一塊兒,當其中一個職責變化時,可能會影響其餘職責的運做,所以要將這些職責進行分離,將不一樣的職責封裝在不一樣的類中,即將不一樣的變化緣由封裝在不一樣的類中,若是多個職責老是同時發生改變則可將它們封裝在同一類中。

單一職責原則是實現高內聚、低耦合的指導方針,它是最簡單但又最難運用的原則,須要設計人員發現類的不一樣職責並將其分離,而發現類的多重職責須要設計人員具備較強的分析設計能力和相關實踐經驗。

優勢:若是類與方法的職責劃分得很清晰,不但能夠提升代碼的可讀性,更實際性地更下降了程序出錯的風險,由於清晰的代碼會讓 bug 無處藏身,也有利於 bug 的追蹤,也就是下降了程序的維護成本。

體悟:單一職責原則更有效的實現開閉原則,它使某一類的做用單一,有利於定位bug,更有利於類的複用和修改

迪米特法則(最少知道原則)

一個軟件實體應當儘量少地與其餘實體發生相互做用

若是一個系統符合迪米特法則,那麼當其中某一個模塊發生修改時,就會盡可能少地影響其餘模塊,擴展會相對容易,這是對軟件實體之間通訊的限制,迪米特法則要求限制軟件實體之間通訊的寬度和深度。迪米特法則可下降系統的耦合度,使類與類之間保持鬆散的耦合關係。

在將迪米特法則運用到系統設計中時,要注意下面的幾點:在類的劃分上,應當儘可能建立鬆耦合的類,類之間的耦合度越低,就越有利於複用,一個處在鬆耦合中的類一旦被修改,不會對關聯的類形成太大波及。在類的結構設計上,每個類都應當儘可能下降其成員變量和成員函數的訪問權限。在類的設計上,只要有可能,一個類型應當設計成不變類。在對其餘類的引用上,一個對象對其餘對象的引用應當降到最低。

優勢:實踐迪米特法則能夠良好地下降類與類之間的耦合,減小類與類之間的關聯程度,讓類與類之間的協做更加直接。

體悟:迪米特法則就是下降耦合的意思

接口分離原則

使用多個專門的接口,而不使用單一的總接口,即客戶端不該該依賴那些它不須要的接口。

根據接口隔離原則,當一個接口太大時,咱們須要將它分割成一些更細小的接口,使用該接口的客戶端僅需知道與之相關的方法便可。每個接口應該承擔一種相對獨立的角色,不幹不應乾的事,該乾的事都要幹。

在使用接口隔離原則時,咱們須要注意控制接口的粒度,接口不能過小,若是過小會致使系統中接口氾濫,不利於維護。接口也不能太大,太大的接口將違背接口隔離原則,靈活性較差,使用起來很不方便。

優勢:避免同一個接口裏麪包含不一樣類職責的方法,接口責任劃分更加明確,符合高內聚低耦合的思想。

體悟:相似於單一職責原則,只是更加細化,使接口也單一職責,這樣在使用的時候,接口的複用性也會變高

六大原則 - 學習心得

六大原則中,開閉原則里氏替換原則依賴倒置原則 聯繫比較緊密,後二者是實現開閉原則重要前提,使用中經過抽象化設計具備很好的可拓展性和可維護性。

知道最少原則 能夠下降耦合,減小沒必要要的交互,主張設計接口和類要簡單易使用,將複雜的邏輯封裝並提供簡單易用的接口。

單一職責原則 使項目中的類和方法根據職責細分,避免單個類負擔太重。職責越多,被複用的可能性就越小或使用起來越麻煩。

接口分離原則 將功能複雜的接口細分紅多個特定功能的接口,只作該作的事情,下降耦合,可是細化粒度不能太細,容易致使接口過多。單一職責原則強調單個類內部根據職責細分的設計,接口分離原則強調類之間的耦合,儘可能創建最小的依賴關係。

註釋:我的以爲,單一職責原則和開閉原則聯繫最爲緊密,依賴倒置原則是開閉原則比較重要的部分,知道最少原則卻是一種思想,最終要達到的效果是開閉原則。
相關文章
相關標籤/搜索