1. 程式人生 > >Java設計模式-六大原則

Java設計模式-六大原則

面向物件的設計,我們通常會涉及到兩個元素:介面,類,及他們之間的協作關係。 對於介面的設計:需要考慮介面隔離原則 對於類的設計:需要考慮類本身的設計,需要考慮類的職責是否單一;對於有繼承關係的類設計,要注意子類是否改變父類的方法,目標是不要改變,子類應該只擴充套件父類的行為(里氏替換原則開閉原則),這樣才能把將來子類變化時產生的影響縮小到最小的範圍。 對於協作關係的設計:做頂層的框架設計時,協作應該是介面之間發生關係,介面之間的呼叫(依賴倒置原則),當1個類需要和 其他類發生呼叫關係時,可以考慮增加1箇中間者來轉發呼叫關係(迪米特法則,不常用),縮小類更變影響的範圍。

筆記來源---設計模式之禪(秦小波著)

六大原則


1. 單一職責原則

Single Responsibility Principle SRP原則

分清職責,介面一定要做到單一職責,方法也要做到,類儘量做到

定義單一職責原則指的是應該有且僅有一個原因引起類的變更

2. 里氏替換原則

Liskov Substitution Principle LSP原則

定義:所有引用基類的地方必須能透明地使用其子類的物件,通俗的來講就是父類能出現的地方子類就可以出現,但是反過來就不行了。子類可以擴充套件父類的功能,但不能改變父類原有的功能。

里氏替換原則為良好的繼承定義了一個規範;

在類中呼叫其他類時務必要使用父類或者介面,如果不能使用父類或者介面,則說明類的設計已經違背了LSP原則;

我們在做系統設計時,經常會定義一個介面或者抽象類,然後編碼實現,呼叫類則直接傳入介面或者抽象類,不關心具體實現;

如果子類不能完整地實現父類的方法,或者父類的某些方法在子類中已經發生“畸變”,則建議斷開父子繼承關係,採用依賴、聚集、組合等關係代替繼承;

在專案中採用里氏替換原則時,儘量避免子類的個性,一旦子類有個性這個子類和父類的關係就很難調和了。

定義包含四層意思:

1) 子類可以實現父的抽象方法,但不能覆寫父類的非抽象方法。 父類中凡是已經實現好的方法(相對於抽象方法而言),實際上是在設定一系列的規範和契約,雖然它不強制要求所有的子類必須遵從這些契約,但是如果子類對這些非抽象方法任意修改,就會對整個繼承體系造成破壞。

2) 子類中可以增加自己特有的方法。

3) 覆寫 或實現父類的方法時,輸入引數可以被放大。(覆寫指的覆寫一個正常方法並重寫,是實現指的是實現介面或者抽象方法)

4) 覆寫或實現父類的方法時輸出結果可以被縮小(若放大,還能用子類替換父類嗎?)

3. 依賴倒置原則

Dependence Inversion Principle DIP原則

定義:

1)高層模組不應該依賴低層模組

2)抽象不應該依賴細節

3)細節依賴抽象

在Java中的表現為:面向介面程式設計 OOP

1)模組間的依賴通過抽象發生,實現類間不發生直接的依賴關係,其依賴關係通過介面或者抽象類產生;

2)介面或抽象類不依賴於實現類

3)實現類依賴於介面或者抽象類

依賴倒置原則可以減少類之間的耦合性,提高系統的穩定性;降低並行開發引起的風險。

要並行開發就要解決模組間的依賴關係,依賴倒置原則正好解決這個問題。

在Java中,只要定義變數就必然要有型別,一個變數可以有兩種型別,表面型別和實際型別,UserDao是表面型別,UserDaoImpl是實際型別。

依賴的三種寫法:依賴是可以傳遞的,只要做到抽象依賴,即使是多層的依賴也沒關係。

1)建構函式傳遞依賴物件

2)Setter方法傳遞依賴物件

3)介面方法中傳入依賴物件

最佳實踐:

1)每個類儘量都有介面或者抽象類

2)變數的表面型別儘量是介面或者抽象類

3)不從具體類派生類

4)儘量不覆寫基類的方法,只實現;

倒置的概念就是所謂的抽象依賴。

4. 介面隔離原則

Interface Segregation Principle ISP原則

把一個臃腫的介面變更為兩個獨立的介面所依賴的原則就是介面隔離原則;

定義

客戶端不應該依賴它不需要的介面

類間的依賴關係應該建立在最小的介面上;

根據介面隔離原則拆分介面時,首先必須滿足單一職責原則;

介面要高內聚,高內聚就是提高介面、類、模組的處理能力,減少對外互動。

定製服務,為不同的使用者定製不同的服務

介面設計要適度,各方都要照顧。

介面和類儘量使用院子介面或原子類來組裝,但是這個原子介面或原子類該怎麼組裝,是一個難題。在實踐中可根據以下標準來衡量:

1)一個介面只服務於一個字模組或業務邏輯

2)通過業務邏輯壓縮介面中的public方法

3)已被汙染的介面儘量去修改,若變更風險大,可用介面卡模式進行轉化處理

4)瞭解業務背景,避免生搬硬套模式。

開發中只能根據,經驗和常識來判斷介面粒度的大小。

5. 迪米特法則

Law of Demter LoD

也稱為最少知識原則:Least Knowledge Principle LKP

描述的是,一個物件應該對其他物件有最少的瞭解,一個類只需要知道自己需要耦合或者呼叫類的public方法即可。

儘量保證風險的不擴散,修改的地方越少,程式碼就越好。

一個類公開的public方法越多,修改時涉及的面也越大,變更的風險也越大。

只和朋友交流:

朋友類的定義:出現在成員變數、方法的輸入輸出引數中的類稱為成員朋友類,而出現在方法體內部的類不屬於朋友類,迪米特法則告訴我們,一個類 只和他的朋友類做交流,老師和體育委員交流、體育委員和學生交流。

在實際中如果遇到,一個方法放在本類中也可以,放在其他類中也合適,那麼你可以堅持這樣一個原則:如果一個方法放在本類中,既不增加類間關係,也 對本類不產生負面影響,那就放置在本類中。

迪米特法則的核心觀念就是類間的解耦,弱耦合。但是也要衡量,既要讓結構清晰,又要高內聚低耦合。

我們在使用原則時,要反覆衡量。

6. 開閉原則

Java世界裡最基礎的設計原則

定義:一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。

根據3W原則介紹

什麼是開閉原則?

軟體實體包括:專案或者軟體產品中按照一定的邏輯規則劃分的模組。

抽象和類

方法

一個軟體產品在開發週期內,肯定會有變化,我們的設計應該儘量適應這些變化,開閉原則則告訴我們儘量通過擴充套件軟體實體的行為來實現變化,而不是修改已有的程式碼來完成變化。

為什麼使用開閉原則? -- 重要性

前五章介紹的原則都是開閉原則的具體形態,開閉原則是精神領袖。

對測試的影響

可提高複用性

可提高可維護性

面向物件開發的要求

如何使用開閉原則?

開閉原則是非常虛的一個原則;

抽象約束、元資料控制模組行為、制定專案章程、封裝變化;

封裝變化有兩層含義,第一將相同的變化封裝到一個介面或抽象類中;第二,將不同的變化封裝到不同的介面或抽象類中。23種設計模式都是從各個不同的角度對變化進行封裝的;

總結:

Single Responsibility Principle

Open Closed Principle

Liskov Substitution Principle

Law of Demeter

Interface Segregation Principle

Dependence Inversion Principle

這六個字母聯合起來 Solid 穩定的;