設(shè)計模式之六大設(shè)計原則整理

1. 單一職責(zé)原則

單一職責(zé)原則的英文名稱是Single Responsibility Principle,簡稱是SRP。單一職責(zé)原則的定義是:應(yīng)該有且僅有一個原因引起類的變更。
SRP的原話解釋是:
There should never be more than one reason for a class to change.
單一職責(zé)原則提出了一個編寫程序的標準,用“職責(zé)”或“變化原因”來衡量接口或設(shè)計是否優(yōu)良,但是“職責(zé)”跟“變化原因”都是不好度量的,要“因地制宜”。

單一職責(zé)適用于接口、類,同時也適用于方法,也就是說,一個方法盡可能做一件事情,一般來說不應(yīng)該讓一個方法承擔(dān)多個職責(zé)。

2. 里氏替換原則

里氏替換原則為良好的繼承定義了一個規(guī)范,一句簡單的定義包含了4層含義。

1、子類必須完全實現(xiàn)父類的方法

2、子類可以有自己的個性。

3、覆蓋或?qū)崿F(xiàn)父類的方法時輸入?yún)?shù)可以被放大。

4、覆寫或?qū)崿F(xiàn)父類的方法時輸出結(jié)果可以被縮小
即如果父類的一個方法的返回值是一個類型T,子類的相同方法(重載或覆寫)的返回值為S,那么里氏替換原則就要求S必須小于等于T,也就是說,要么S和T是同一個類型,要么S是T的子類。

好像挺難理解的,查找了一些資料。著名技術(shù)作家Robert Martin在1996年為《C++ Reporter》寫了一篇題為《The The Liskov Substitution Principle》的文章,專門介紹LSP。在Martin的文章中,他給了LSP一個解釋:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

意思是:“使用指向基類的指針或引用的函數(shù),必須能夠在不知道具體派生類對象類型的情況下使用它們?!痹?002年,Martin在他出版的《Agile Software Development Principles Patterns and Practices》一書中,又進一步簡化為:

Subtypes must be substitutable for their base types。子類必須能替換掉它們的父類。
這樣理解起來就比較順利了。

3. 依賴倒置

依賴倒置原則的原始定義是:

High level modules should not depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstractions.

包含了三層含義:

  • 高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象;
  • 抽象不應(yīng)該依賴細節(jié);
  • 細節(jié)應(yīng)該依賴抽象。

這一原則在Java語言中的表現(xiàn)就是:
1、模塊間的依賴通過抽象發(fā)生,實現(xiàn)類之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系
是通過接口或抽象類產(chǎn)生的;
2、接口或抽象類不依賴于實現(xiàn)類;
3、實現(xiàn)類依賴接口或抽象類。

一般抽象是不變的,而具體是易變的。每個較高層次都為它所需要的服務(wù)聲明一個抽象接口,較低的層次實現(xiàn)這些抽象接口,每個高層類都通過該抽象接口使用下一層的服務(wù),接口屬于高層,低層要實現(xiàn)高層的接口,因此現(xiàn)在是低層依賴于高層。是依賴關(guān)系倒置和接口所有權(quán)的倒置。在周圍環(huán)境發(fā)生變化的時候,如果設(shè)計可以做到不怎么發(fā)生改變,那這樣的設(shè)計就是好的。

4. 接口隔離原則

接口隔離原則的原始定義是:

Clients should not be forced to depend upon interfaces that they don't use.
客戶端不應(yīng)該依賴它不需要的接口。
The dependency of one class to another one should depend on the smallest possible interface.
類間的依賴關(guān)系應(yīng)該建立在最小的接口上。

這兩個定義概括起來就是,應(yīng)該盡量建立單一接口,不要建立臃腫的接口,接口應(yīng)該盡量細化。

接口分離的手段主要有以下兩種:

  1. 委托分離,通過增加一個新的類型來委托客戶的請求,隔離客戶和接口的直接依賴,但會增加系統(tǒng)開銷。
  2. 多重繼承分離,通過接口多繼承來實現(xiàn)客戶需求。

5. 迪米特法則

迪米特法則(Law of Demeter)又叫最少知道原則(Least Knowledge Principle),1987年秋天由美國Northeastern University的Ian Holland提出,被UML的創(chuàng)始者之一Booch等普及。后來,因為在經(jīng)典著作《 The Pragmatic Programmer》中提出而廣為人知。

迪米特法則還有一個英文解釋是:Only talk to your immediate friends。

一個對象應(yīng)該對其他對象有最少的了解。通俗地講,一個類應(yīng)該對自己需要耦合或調(diào)用的類知道得最少。一個類公開的public屬性或方法越多,修改時涉及的面也就越大,變更引起的風(fēng)險擴散也就越大。在設(shè)計時需要反復(fù)衡量,是否可以減少public方法和屬性,是否可以修改為private、package-private、protected等訪問權(quán)限,是否可以加上final關(guān)鍵字等。迪米特法則要求類盡量不要對外公布太多的public方法和非靜態(tài)的public變量,盡量內(nèi)斂,多使用private、package-private、protected等訪問權(quán)限。

6. 開閉原則

開閉原則的定義:
Software entities like classes,modules and functios should be open for extemsion but closed for modifications.

一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。一個軟件產(chǎn)品只要在生命期內(nèi),都會發(fā)生變化,既然變化是一個既定的事實,我們應(yīng)該在設(shè)計時盡量適應(yīng)這些變化,以提高項目的穩(wěn)定性和靈活性。開閉原則要求盡量通過擴展軟件實體的行為來實現(xiàn)變化,而不是通過修改已有的代碼來完成變化。

如何做到開閉原則: 抽象、封裝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 整理總結(jié)自《設(shè)計模式之禪》一書 1 單一職責(zé)原則 Single Responsibility Principle ...
    笑哥哥閱讀 460評論 0 1
  • 1、單一職責(zé)原則2、里氏替換原則3、依賴倒置原則4、接口隔離原則5、迪米特原則6、開閉原則 1、單一職責(zé)原則 定義...
    安靜點就睡吧閱讀 396評論 0 1
  • 目錄: 設(shè)計模式六大原則(1):單一職責(zé)原則 設(shè)計模式六大原則(2):里氏替換原則 設(shè)計模式六大原則(3):依賴倒...
    加油小杜閱讀 739評論 0 1
  • 對比是我們每個人都有的一種習(xí)慣,有的人把這種習(xí)慣進行了升級,就成為了攀比。大多數(shù)人其實并沒有特別強的攀比心理,但是...
    善行無痕閱讀 224評論 0 0
  • 大概沒有人會想到這場一開始注定要持續(xù)至少三個月的苦逼深山生活,竟然因為一場地震變成了為期半個月的生死旅游。北京時間...
    想吃熱豆腐的心急boy閱讀 520評論 4 1