物件導向設計的 10 條戒律
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
不,這不是上帝說的。
這也不是Jon Skeet / Martin Fowler / Jeff Atwood / Joel Spolsky(可以用你最喜歡的技術專家的替換這些名字)說的。
我們正在審查一些程式碼,並開始討論為什麼我們走捷徑,不遵循常識原則。雖然每個人在對待關於類應該如何基於功能上下文來構建的問題上都有自己的智慧,但仍然有一些基本原則值得我們在設計類的時候牢牢記住。
I.遵循單一職責原則
每個類都應該有一個並且只有一個引起它變化的原因。這不僅適用於類,方法也是如此。不知道你有沒有見到過那些長篇大論的冗餘的類和方法,當將它們寫到紙上的時候,簡直就是懶婆娘的裹腳布——又臭又長?好吧,我們要提出的觀點是不要這樣做。
該原則的要點就是每個類或方法都有一個存在的理由。如果類被命名為Loan,那麼它就不應該處理銀行帳戶的相關細節。如果方法被命名為GetLoanDetails,那麼它應該負責獲取貸款的詳細資訊!
II.遵循開放封閉原則
這一條使你能夠思考你的系統將如何適應未來的變化。它指出,系統應該允許新增新的功能,但對現有程式碼的更改要做到最少。因此,設計對於擴充套件應該是開放的,但對於修改應該是封閉的。在我們的例子中,開發人員做了這樣的事情:
public class PersonalLoan { public void Terminate() { //Execute Termination related rules here and terminate a personal loan } } public class AutoLoan { public void Terminate() { //Execute Termination related rules here and terminate a personal loan } } public class LoanProcessor { public void ProcessEarlyTermination(object loan) { if ( loan is PersonalLoan ) { //Personal Loan processing } else if (loan is AutoLoan) { //Auto Loan Processing } } }
LoanProcessor的問題是,當有一種新型別的Loan,例如HomeLoan出現的時候,它將不得不改變。結構最好是這樣:
public abstract class Loan { public abstract void Terminate(); } public class PersonalLoan: Loan { public override void Terminate() { //Execute Termination related rules here and terminate a personal loan } } public class AutoLoan: Loan { public override void Terminate() { //Execute Termination related rules here and terminate a personal loan } } public class LoanProcessor { public void ProcessEarlyTermination(Loan loan) { loan.Terminate(); } }
這樣的話,如果新增了新型別的Loan,那麼LoanProcessor也不會受影響。
III.嘗試使用組合優於繼承
如果不能正確地遵循這一條原則,那麼可能會導致脆弱的類層次。這個原則真的很簡單,只需要問一個問題——如果我要看子類,那麼我能不能說“Child是Parent的一種型別?”或者,它更像“Child某種程度上是Parent的一種型別?“
始終對第一個問題使用繼承,因為它將允許使用Child無論Parent在哪裡。這也將允許你能夠實現另一個稱為Liskov替代原則的設計原則。並且在你想部分使用一個類的功能的時候使用組合。
IV.封裝資料和行為
大多數開發人員只做資料封裝,忘記封裝基於上下文而變化的程式碼。不但隱藏類的私有資料很重要,而且建立被良好封裝的作用於私有資料的方法也很重要。
V.類遵循鬆散耦合原則
這與封裝正確的行為是相輔相成的。如果行為被很好地封裝在類中,那麼就只能建立鬆散耦合的類。我們可以通過依賴於抽象而不是實現來做到鬆散耦合。
VI.使類高度內聚
我們不應該在不同的類之間散開資料和行為。應該努力使類不洩露/打破實現到其他類的細節。這意味著不允許類有程式碼,因為這樣超出了它存在的目的。當然,有一些設計範例,如CQRS,會希望你在不同的類中隔離某些型別的行為,但它們只用於分散式系統。
VII.編碼介面而不是實現
這促進了鬆散耦合原則,並使得我們能夠改變底層實現或引入新的實現,而不影響使用它們的類。
VIII.保持DRY(Don’t Repeat Yourself)
也是一個宣告不要在兩個不同的地方重複相同程式碼的設計原則。也就是說,特定功能或演算法應當,僅,在一個地方實現。如果重複實現的話,則會導致維護問題。與此相反的是WET原則——Write Everything Twice。
IX.最少知識原則,也叫做迪米特法則。
這個原則宣告物件不應該知道它協作物件的內部細節。它被著名地稱為——與朋友交流,不要和朋友的朋友交流。類應該只能呼叫它正在協作的類的公共資料成員。不應該被允許訪問由那些資料成員組成的類的行為或資料。如果不能正確遵守,則會導致緊密耦合,從而建立出更難改變的系統。
X.遵循好萊塢原則:Don’t Call Us, We’ll Call You
這能夠打破條件流邏輯的模型,並允許基於事件執行程式碼。這要麼通過事件回撥,要麼通過注入介面的實現來完成。依賴注入,控制反轉或觀察者設計模式都是這個原則的好例子。這個原則促進了類之間的鬆散耦合,並使得實現非常可維護。
譯文連結:http://www.codeceo.com/article/10-commandments-of-ood.html
英文原文:10 Commandments of Object-Oriented Design
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- 無我程式設計的 10 條戒律程式設計
- 61條物件導向設計的經驗原則物件
- Java程式設計師應該遵循的10條戒律Java程式設計師
- iOS 開發之 OOA (物件導向分析) & OOD (物件導向設計)& OOP (物件導向程式設計)iOS物件OOP程式設計
- Guru of the Week 條款13:物件導向程式設計 (轉)物件程式設計
- 物件導向程式設計物件程式設計
- PHP物件導向程式設計的61條黃金法則PHP物件程式設計
- JS物件導向設計-建立物件JS物件
- Scala的物件導向程式設計物件程式設計
- JS物件導向的程式設計JS物件程式設計
- javascript:物件導向的程式設計JavaScript物件程式設計
- 物件導向的設計原則物件
- js物件導向設計---建立物件的方式JS物件
- [.net 物件導向程式設計基礎] (2) 關於物件導向程式設計物件程式設計
- 十三、物件導向程式設計物件程式設計
- JS物件導向設計模式JS物件設計模式
- js物件導向程式設計JS物件程式設計
- 程式設計思想 物件導向程式設計物件
- Java--物件導向設計Java物件
- 十六、物件導向程式設計物件程式設計
- 物件導向系統設計物件
- 物件導向設計與DROOLS物件
- perl 物件導向程式設計物件程式設計
- LotusScript物件導向程式設計物件程式設計
- Javascript 物件導向程式設計JavaScript物件程式設計
- 物件導向——類設計(一)物件
- 物件導向設計原則物件
- Delphi物件導向程式設計的20條規則(By Marco Cantu)(rule 1-10) (轉)物件程式設計
- JS物件導向程式設計(一):物件JS物件程式設計
- [筆記]物件導向的程式設計筆記物件程式設計
- 物件導向的基本設計原則物件
- JavaScript 中的物件導向程式設計JavaScript物件程式設計
- 【軟體工程】物件導向的設計軟體工程物件
- 物件導向的JavaScript程式設計 (轉)物件JavaScript程式設計
- 全網最適合入門的物件導向程式設計教程:00 物件導向設計方法導論物件程式設計
- JavaScript 遊戲中的物件導向的設計JavaScript遊戲物件
- JavaScript遊戲中的物件導向的設計JavaScript遊戲物件
- JavaScript物件導向程式設計理解!JavaScript物件程式設計