Java面向物件設計
面向物件設計的SOLID原則:
S.O.L.I.D是面向物件設計和程式設計(OOD&OOP)中幾個重要編碼原則(Programming Priciple)的首字母縮寫。
SRP The Single Responsibility Principle :單一責任原則
當需要修改某個類的時候原因有且只有一個(THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE)。換句話說就是讓一個類只承擔一種責任,當這個類需要承當其他責任的時候,就需要分解這個類。
從面向物件角度解釋這個原則為:"引起類變化的因素永遠不要多於一個。" 或者說 "一個類有且僅有一個職責"。這似乎不太好理解,特別是"引起類變化的因素永遠不要多於一個。"這句話更是有點虛,讓人有點摸不著頭腦。我們通常都說“低耦合,高內聚”。在我看來,這裡的"單一職責"就是我們通常所說的“高內聚”,即一個類只完成它應該完成的職責,不能推諉責任,也不可越殂代皰,不能成為無所不能的上帝類。如果你的團隊中實施寬鬆的“程式碼集體所有權”,在編碼的過程中出現許多人同時修改(維護)同一個類的現象,而且成員之間的溝通不夠及時,主動和暢通的話,那麼時間一長,就很可能出現“承擔過多職責”的上帝類。這時,提煉基類/介面和提煉類重構將能幫助我們消除或減輕這種設計臭味。
OCP The Open Closed Principle :開閉原則
軟體實體應該是可擴充套件,而不可修改的。也就是說,對擴充套件是開放的,而對修改是封閉的。
從面向物件設計角度看,這個原則可以這麼理解:"軟體實體(類,模組,函式等等)應當對擴充套件開放,對修改閉合。" 通俗來講,它意味著你(或者類的客戶)應當能在不修改一個類的前提下擴充套件這個類的行為。在OOD裡,對擴充套件開放意味著類或模組的行為能夠改變,在需求變化時我們能以新的,不同的方式讓模組改變,或者在新的應用中滿足需求。也就是說,對擴充套件是開放的,而對修改是封閉的。我們通常都說:向系統中增加功能時應該只是新增新程式碼,而應該儘量少的修改原始碼。在我看來,這就是遵循開放封閉原則所能帶來的效果。曾經在網上看到過這樣一句話“哪裡變化,封裝哪裡”。這其實就是說,我們要將系統中可能變化的地方封裝起來,即對修改封閉。同時,為了應對系統需求(功能)的擴充套件,需要抽象。
LSP The Liskov Substitution Principle :里氏替換原則
當一個子類的例項應該能夠替換任何其超類的例項時,它們之間才具有is-A關係。
Liskov's 替換原則意思是:"子型別必須能夠替換它們的基型別。"或者換個說法:"使用基類引用的地方必須能使用繼承類的物件而不必知道它。" 這個原則正是保證繼承能夠被正確使用的前提。通常我們都說,“優先使用組合(委託)而不是繼承”或者說“只有在確定是 is-a 的關係時才能使用繼承”,因為繼承經常導致”緊耦合“的設計。
ISP The Interface Segregation Principle :介面分離原則
不能強迫使用者去依賴那些他們不使用的介面。換句話說,使用多個專門的介面比使用單一的總介面總要好。
這個原則的意思是"客戶端不應該被迫依賴於它們不用的介面。" 也就是說,一個介面或者類應該擁有儘可能少的行為(那麼,什麼叫儘可能少?就是少到恰好能完成它自身的職責),這也是保證“軟體系統模組的粒度儘可能少,以達到高度可重用的目的。介面包含太多的方法會降低其可用性,像這種包含了無用方法的"胖介面"會增加類之間的耦合。如果一個類想實現該介面,那麼它需要實現所有的方法,儘管有些對它來說可能完全沒用,所以這樣做會在系統中引入不必要的複雜度,降低程式碼的可維護性或魯棒性。介面分離原則確保實現的介面有它們共同的職責,它們是明確的,易理解的,可複用的。
DIP The Dependency Inversion Principle : 依賴倒置原則
1. 高層模組不應該依賴於低層模組,二者都應該依賴於抽象
2. 抽象不應該依賴於細節,細節應該依賴於抽象
這個原則的意思是:高層模組不應該依賴底層模組,兩者都應該依賴其抽象。其實又是”面向介面程式設計,不要面向實現程式設計“的內在要求。