Java設計模式面試題 01 - 六大原則
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 穩定的;
筆記來源---設計模式之禪(秦小波著)