設計模式遵循的七大原則


 

單一職責原則:

“單一職責原則(Single responsibility principle),意思就是說,功能要單一? 可以簡單的這么理解,它的准確解釋是:就一個類而言,應該僅有一個引起它變化的原因。我們在做編程的時候,很自然的會給一個類各種各樣的功能,比如我們寫一個窗體應用程序,一般都會生產一個form這樣的類,於是我們把各種各樣的代碼,想商業運算呀,數據訪問sql語句呀,都寫到這樣的類中,這就意味着,無論什么需求要來,你都要更改這個窗體類,這其實是很糟糕的,維護麻煩,復用不可能,也卻反靈活性。”
 
單一職責原則(SRP),就一個類而言,應該僅有一個引起它變化的原因。
 
“如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受意想不到的破壞。”

開放封閉原則:

“開放封閉原則(OCP)(Open Closed Principle):是說軟件實體(類、模塊、函數等等)應該可以擴展,但是不可以修改。”
 

這個原則其實有兩個特征,一個是“對於擴展時開放的”,另一個是“對於更改時封閉的”

“我們在做任何系統的時候,不能指望系統一開始需求確定,就再也不會變化,這是不現實的。既然需求一定會變化,如何應對變化時,設計的軟件可以相對容易修改,不至於說,新需求一來,就把整個程序推倒重來。怎樣的設計才能面對需求的改變卻可以保持相對穩定,從而使得系統可以在第一個版本以后不斷推出新的版本呢?”

 

設計軟件要容易維護有不容易出問題的最好的辦法,就是多擴展,少修改。開放封閉原子的意思就是說,設計的時候,時刻要考慮,盡量讓這個類足夠好,寫了就不要去修改了,如果新的需求來,我們增加一些類就好了,原來的代碼能不動就不懂。但是無論多么的封閉,都會存在一些無法對之封閉的變化。既然不可能完全封閉,設計人員必須對於他設計的模塊應該對哪種變化封閉做出選擇。他必須先猜出最有可能變化的種類,然后構造抽象來隔離那些變化。但是變化時很難預測的,但我們可以在發生小變化時,就及早去想辦法應對發生更大變化的可能。也就是等到變化發生時立即采取行動。

在我們最初編寫代碼時,假設變化不會發生。當發生變化時,我們就創建抽象來隔離以后發生的同類變化。面對需求對程序的改動是增加新代碼進行的,而不是改現有的代碼。這是開放封閉原則的精神所在。

 

開放封閉原則是面向對象的核心所在。遵循這個原則可以帶來面向對象技術的巨大好處,可維護、可擴展、可復用、靈活性。開發人員應該進隊程序中呈現出頻繁變化的那些部分做出抽象,然而,對於程序中的每個部分都刻意地進行抽象同樣不是一個好主意。拒絕不成熟的抽象和抽象本身一樣重要。

依賴倒轉原則:

本節先是通過小菜為妹紙修電腦的例子引出了電腦制造的一個原則:內部封轉,明確接口,統一標准。具體說來就是,各個部件的具體實現和制造不盡相同,但是他們都遵循一個接口標准,使得各個部件可以無縫的鏈接起來;同時在這個接口之上可以進行有限的擴展。電腦配件之間的關系還體現另一個基本原則:強內聚,松耦合。

電腦配件還體現了前面說過兩個原則,單一職責原則和開放封閉原則。這里着重強調一個新的原則,叫依賴倒轉原則(DIP)(Dependence Inversion Principle)。依賴倒轉原則,原話解釋是抽象不應該依賴細節,細節應該依賴於抽閑。說白了,就是要針對接口編程,不要對實現編程。回到例子上,主板,cpu等都是針對接口設計的,如果針對實現來設計,內存就要對應到具體的某個品牌的主板,就會出現換內存需要把主板也換了的尷尬。

依賴倒轉原則:

A. 高層模塊不應該依賴底層模塊。兩個都應該依賴抽象

B. 抽象不應該依賴細節。細節應該依賴抽象。

為什么需要依賴倒轉?面向對象開發時,為了使得常用代碼可以復用,一般都會把這些代碼寫出許多的函數程序庫,新項目中去調用這些底層的函數就可以了。比如數據庫訪問模塊等。問題也出在這里,當有新項目時,發現業務邏輯的高層模塊都是一樣的, 但客戶卻希望使用不同的數據庫或存儲信息的方式。我們希望再次利用這些高層模塊,但高層模塊與低層模塊綁定在一起的,沒法復用這些高層模塊,這就麻煩了。而如果不管高層還是低層模塊,它們都依賴於抽象,具體一點就是借口或者抽象類,只要借口是穩定的,那么任何一個的更改都不用擔心受其它受到影響。這就使得無論高層還是低層模塊都可以很容易的被復用。

但為什么依賴了抽象的接口或抽象類,就不怕更改呢?這里需要講到里氏代換原則。具體說來是一個軟件實體如果使用的是一個父類的話,那么一定適用於其子類,而且察覺不出父類和子類對象的區別。也就是說,在軟件里面,把父類都替換成它的子類,程序的行為沒有變化。簡單來說,子類型必須能夠替換掉他們的父類型。為什么需要這樣呢?只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才能真正被復用,而子類也能夠在父類的基礎上增加新的行為。

書中舉了一個例子,貓是繼承動物類的,以動物的身份擁有吃、喝、跑、叫等行為。當某一天,我們需要狗、牛、羊也擁有類似的行為,由於他們都是繼承與動物,所以除了更改實例化的地方,程序其他處不需要改變。
 
 
再回頭來看依賴倒轉原則,高層模塊不應該依賴低層模塊,兩個都應該依賴抽象,如下圖:
 

里氏代換原則:

里氏代換原則(LSP)(Liskov Substitution Principle LSP): 子類必須能夠代替它們的父類型。這里的父類型也可指接口。這個原則其實是對開放-封閉原則的補充。因為開發-封閉原則的核心就是抽象化,而里氏代換原則則是抽象化的規范。
 
一個軟件實體如果使用的是一個父類的話,那么一定適用於其子類,而且它察覺不出父類對象和子類對象的區別,也就是說,在軟件里面,把父類都替換成它的子類,程序的行為沒有變化,簡單的說, 子類型必須能夠替換掉它們的父類型。也正因為有了這個原則,使得繼承復用成為了可能,只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才能真正被復用,而子類也能夠在父類的基礎上添加新的行為。
 
比方說,貓是繼承動物類的,以動物的身份擁有吃、喝、跑、叫等行為,可當某一天,我們需要狗、牛、羊也擁有類似的行為,由於他們都是繼承與動物,所以除了更改實例化的地方,程序其他處不需要修改。正式有了里氏代換原則,才使得開放-封閉成為了可能。由於子類型的可替換性才使得使用父類類型的模塊在無需修改的情況下就可以擴展。

迪米特法則:

迪米特法則:如果兩個類不必彼此直接通信,那么這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。

1.迪米特法則首先強調的前提是在類的結構設計上,每一個類都應當盡量降低成員的訪問權限,也就是說,一個類包裝好自己的private狀態,不需要讓別的類知道的字段或行為就不要公開。
2.類之間的耦合越弱,越有利於復用,一個處在弱耦合的類被修改,不會對有關系的類造成波及。也就是說,信息的隱藏促進了軟件的復用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM