面向對象六大設計原則

設計原則和設計模式的關係

面向對象的分析設計,需要遵循六大設計原則,這些設計原則大都會從思想上指導面向對象分析設計的正確方向,掌握這些原則能幫助我們更好的理解面向對象的概念,也能更好的理解設計模式。因爲在實際開發中,也需要綜合考慮業務需求、功能、實現難度、系統性能、時間與空間等很多方面的問題,所以很少做到完全遵守,總是在有意無意的違反一些或者是部分設計原則,這時便需要綜合權衡其利弊。
設計模式是針對某個場景下某些問題的某個具體的解決方案。也就是說設計模式就是這些設計原則的一些具體的體現,因此設計模式也是應該遵守這些原則的。所以,學習設計模式,首先要學習的就是設計原則。

六大設計原則

  • 單一職責原則——SRP
  • 開閉原則——OCP
  • 裏式替換原則——LSP
  • 依賴倒置原則——DIP
  • 接口隔離原則——ISP
  • 迪米特原則——LOD

六大設計原則關係圖

1.

1.單一職責原則 (Single Responsibility Principle)

單一職責原則,簡稱SRP,定義是應該有且僅有一個類引起類的變更,即:一個類只負責一個職責。

優點:

  • 類的複雜性降低,實現什麼職責都有明確的定義;
  • 邏輯變得簡單,類的可讀性提高了,而且,因爲邏輯簡單,代碼的可維護性也提高了;
  • 變更的風險降低,因爲只會在單一的類中的修改。

2.里氏替換原則 (Liskov Substitution Principle)

單一職責原則,簡稱LSP。定義如下:

複雜定義:如果對每一個類型爲T1的對象o1,都有類型爲T2的對象o2,使得以T1定義的所有程序P在所有對象o1都替換成o2的時候,程序P的行爲都沒有發生變化,那麼類型T2是類型T1的子類型。

簡單定義:所有引用基類的地方必須能透明地使用其子類的對象。

通俗地講,就是:子類可以擴展父類的功能,但不能改變父類原有的功能。

面向對象的三大特徵是封裝、繼承和多態。其中的繼承,當子類繼承父類時,雖然可以複用父類的代碼,但是父類的屬性和方法對子類都是透明的,子類可以隨意修改父類的成員。若需求變更,子類對父類的方法進行了一些複寫的時候,其他的子類可能就需要隨之改變,這在一定程度上就違反了封裝的原則,解決的方案就是引入里氏替換原則。

里氏替換原則爲良好的繼承定義了一個規範,它包含了4層含義:

  • 子類可以實現父類的抽象方法,但是不能覆蓋父類的非抽象方法。
  • 子類可以有自己的個性,可以有自己的屬性和方法。
  • 子類覆蓋或重載父類的方法時輸入參數可以被放大。
  • 子類覆蓋或重載父類的方法時輸出結果可以被縮小,也就是說返回值要小於或等於父類的方法返回值。

3.依賴倒置原則 (Dependence Inversion Principle)

依賴倒置原則,簡稱DIP,定義是:

高層模塊不應該依賴底層模塊,兩者都應該依賴其抽象;

抽象不應該依賴細節;

細節應該依賴抽象。

不可分割的原子邏輯就是底層模塊,原子邏輯的再組裝就是高層模塊。
在Java中,抽象是指接口或抽象類,兩者都不能被實例化;而細節是實現接口或繼承抽象類產生的類,也就是可以被實例化的實現類。依賴倒置原則是指模塊間的依賴是通過抽象來發生的,實現類之間不發生直接的依賴關係,其依賴關係是通過接口是來實現的,這就是俗稱的面向接口編程。所以說依賴倒置原則的核心就是要我們面向接口編程,理解了面向接口編程,也就理解了依賴倒置。

4.接口隔離原則 (Interface Segregation Principle)

接口隔離原則,簡稱ISP,定義是:

客戶端不應該依賴它不需要的接口

也就是說客戶端需要什麼接口就提供什麼接口,把不需要的接口剔除掉,這就需要對接口進行細化,保證接口的純潔性。換成另一種說法就是,類間的依賴關係應該建立在最小的接口上,也就是建立單一的接口。

建立單一接口,這裏需要和單一職責區分。單一職責原則要求的是類和接口職責單一,注重的是職責,一個職責的接口是可以有多個方法的,而接口隔離原則要求的是接口的方法儘量少,模塊儘量單一,如果需要提供給客戶端很多的模塊,那麼就要相應的定義多個接口,不要把所有的模塊功能都定義在一個接口中,那樣會顯得很臃腫。

5.迪米特原則 (Law of Demeter)

迪米特原則,簡稱LoD,也被稱爲最少知識原則,它描述的規則是:

一個對象應該對其他對象有最少的瞭解

也就是說,一個類應該對自己需要耦合或調用的類知道的最少,類與類之間的關係越密切,耦合度越大,那麼類的變化對其耦合的類的影響也會越大,這也是我們面向設計的核心原則:低耦合,高內聚。

迪米特法則還有一個解釋:只與直接的朋友通信。

什麼是直接的朋友呢?每個對象都必然與其他對象有耦合關係,兩個對象的耦合就成爲朋友關係,這種關係的類型很多,例如組合、聚合、依賴等。其中,我們稱出現成員變量、方法參數、方法返回值中的類爲直接的朋友,而出現在局部變量中的類則不是直接的朋友。也就是說,陌生的類最好不要作爲局部變量的形式出現在類的內部。

6.開閉原則  (Open Closed Principle)

開閉原則,簡稱OCP,是Java世界裏最基礎的設計原則。定義是:     

一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。


簡而言之,在編程過程中,需求會不斷變化,我們的軟件實體應該通過擴展來方式來實現變化,而不是通過修改已有的代碼實現變化。所以,我們的程序需要有易於擴展、易於維護、易於升級等特性。
遵循開閉原則的最好手段是抽象,用抽象構建框架,用實現擴展細節。因爲抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟件架構的穩定。而軟件中易變的細節,我們用從抽象派生的實現類來進行擴展,當軟件需要發生變化時,我們只需要根據需求重新派生一個實現類來擴展就可以了。當然前提是我們的抽象要合理,要對需求的變更有前瞻性和預見性才行。但從開閉原則的角度說,更好的方式是面向接口編程,這樣可以更好的擴展性,同時也可降低耦合,可提高系統的穩定性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章