設計模式之設計原則
這軟件設計過程中,有六大設計原則:
- 單一職責原則
- 里氏替換原則
- 依賴倒置原則
- 接口隔離原則
- 迪米特法則
- 開閉原則
由于軟件開發過程中,根據業務不同等因素形成了各種復雜的而不可預料的需求,遵守原則,讓項目開發過程與維護過程中,減少付出更多的時間與努力而達到更好的實現功能。需要對經驗,不斷總結,不斷實踐,對將設計模式使用的更熟練,對軟件開發起到意想不到的作用。
以下對六大設計原則,鄙人的一些簡單述說:
單一職責原則
定義:
做到有且只有一個原因引起類的變更,也就是說一個接口做一件事,這件事能概況某一事物的某一職責。
問題由來:
類T負責兩個不同的職責,職責P1,職責P2,當職責P1需求發生變化時,需要修改P2功能,有可能會導致原本運行正常功能發生故障
解決方案:
將T的P1,P2兩個職責使用T1,T2分別完成,T1負責P1功能,T2負責P2功能,當T1發生改變,T2不會發生改變,T2發生改變,T1也不會發生改變。
由于每個職責都進行分開,會出現大量類,當某一職責進行分解時,需要修改大量的代碼,此時修改職責類中的代碼違反單一職責(代碼級別,方法級別),減少大量類出現。
適用情況:
- 接口
必要時可以將接口中的屬性和行為進行分解,這樣可以做到單一職責。 - 方法
方法中的參數過多,可以對方法的參數進行分解,可以做到單一職責。
總結:
使用接口和方法的方式,盡量做到只有一個原因引起對這個類的改變。
單一職責原則,不只是面向對象編程,還適合模塊化編程等。
在實際項目中,由于功能過于復雜等原因做到該原則,還是挺難的,盡量做到單一職責原則,。
里氏替換原則
定義:
簡單點說就是只要父類出現的地方,子類就可以出現,且替換成子類后,也不能出現任何錯誤與異常(子類出現后,父類不能因為子類的出現導致父類出問題),導致出現錯誤原因:子類繼承父類,重寫父類方法后,這時父類方法功能就失效,發生變化。
意義:
子類可以擴展父類的功能,但不能改變父類原有的功能
繼承機制的優點:
- 代碼共享,減少創建類的工作量
- 提高代碼的重用性
- 子類可以形似父類,又異于父類,
- 提高父類的擴展性,實現父類的方法即可隨意而為
缺點:
- 繼承是入侵性的,(擁有父類的所有屬性和方法)
- 降低了代碼的靈活性,(由于父類屬性的約束,導致子類的約束更多)
- 增強了耦合性,(當父類的常量,變量,方法被修改,需考慮對子類的影響)
總結: 當違反了里氏替換原則后,可以將父類和子類抽取出更加通用的基類,使用依賴,聚合,組合燈關系,降低繼承的缺點。
依賴倒置原則
定義:
- 高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象
- 抽象不應該依賴細節
- 細節應該依賴抽象
在代碼中可以理解成:
- 模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系是通過接口或者抽象類產生的
- 接口或者抽象類不依賴于實現類
- 實現類依賴于接口或者抽象類
此時可以更簡潔的理解成: 面向接口編程
總結:
依賴導致原則本職就是通過抽象(抽象類或者接口)使各個類或者模塊實現彼此獨立,不相互影響,實現模塊的松耦合。
在實際使用項目中,盡量使用如下規則:
每個類盡量都要有接口或者抽象類,或者抽象類和接口都有(依賴倒置原則定義要由抽象才能實現依賴倒置)
變量表面類型盡量是接口或者抽象類
任何類都不應該從具體類派生
盡量不要重寫基類已經寫好的方法(里式替換原則)
結合里式替換原則來使用(依賴原則和里式原則總結:接口負責定義public屬性和方法,并聲明與其他對象的依賴關系,抽象類負責公共構造部分的實現,實現類準確的實現業務邏輯,并在適當的時候對父類進行細化)
接口隔離原則
我們先來看接口的定義 :
實例接口 : 在 Java 中聲明一個類,然后用 new 關鍵字產生一個實例,它是對一類事物的描述,可以看成是一個接口
類接口 : 使用 interface 定義的接口
隔離的的理解 :
- 客戶端不應該依賴它不需要的接口
- 類之間的依賴關系應該建立在最小的接口上
概括 : 建立單一接口,不要建立臃腫龐大的接口,也就是接口盡量細化,接口中的方法盡量少
這個是開閉原則的基礎,具體內容:針對接口編程,依賴于抽象而不依賴于具體。
接口隔離原則的約束條件 :
接口要高內聚,意思就是提高接口,類,模塊的處理能力,減少對外的交互,再具體一點就是在接口中盡量減少對外的 public 方法,通過業務邏輯壓縮接口中的 public 方法
定制服務,就是單獨為一個個體提供優良的服務,比如我們寫用戶模塊的時候,需要給用戶提供查詢信息,修改密碼,注冊用戶等信息,當管理員執行相同操作的時候,一般人會復用這些方法,
然后在這個的基礎上再增加管理員自己的方法,這種設計方法肯定是有問題的,這樣設計,當你修改了普通用戶調用的接口實現時,管理員的實現也會發生不可預測的改變,我們應該為管理員單獨寫一個接口
接口設計是有限度的,接口的設計粒度越小,系統越靈活,這是肯定的,但靈活的同時帶來的問題是 結構復雜化,開發難度增加, 可維護性降低
一個接口只服務于一個子模塊或業務邏輯
已經被污染了的接口,盡量去修改 ,若修改的風險較大,則采用適配器模式進行轉化處理
了解環境,拒絕盲從,不要一味的去套設計模式,有的時候不用比用了更好,也不要去照搬別人的設計方法,他的方法到你這不一定效果就好,畢竟業務邏輯不一樣
迪米特法則
定義 : 迪米特法則也叫最少知識原則,含義是 一個對象應該對其他對象有最少的了解,這個應該很好理解,就是降低各模塊之間的耦合
開閉原則
定義 : 一個軟件實體如類,模塊和函數應該對擴展開放,對修改關閉,開閉原則也是其他五個原則的基石