面向對象設計的11原則

面向對象設計是什麼?都包含了哪些內容?它所帶來的好處是什麼?需要你爲之付出些什麼?在如今這個年代,問這些問題似乎顯得很愚蠢,因爲這年頭幾乎每位軟件開發人員都知道如何使用某種面向對象編程語言。可是這個問題還是很重要,因爲在我看來,絕大多數人在使用這些語言的時候並不知道爲什麼,而且也不知該如何最充分的運用它們。

軟件業曾經爆發過的所有變革裏,其中曾經有兩個派系如此廣泛的深入人心,它們就是結構化編程和麪向對象編程。所有主流的現代編程語言都被它們兩個激烈的影響着。實際上,要想不像結構化和麪向對象編程的樣子來編寫程序都是一件難事。我們的主流編程語言都沒有goto,因此它們服從了結構化編程中最重要的禁令。我們的大多數主流編程語言都是基於類的,而且不支持在類以外定義函數或是變量,因此也避免了面向對象編程中最容易墜入的陷阱。

用這些編程語言所編寫的程序可能看起來是結構化的或是面向對象的,可是“看起來”是會欺騙人的。當今的編程語言經常不顧他們所從屬那種派系的編程語言的基本原則。我會在另篇blog中再探討結構化編程的原則,本篇,我想要談論的是面向對象編程的基本原則。

這些原則着重於OOD中的依賴管理方面,而淡化抽象與建模方面。這並不是說OO在抽象方面不夠強大,或是OO不適合構建模型。當然有很多人都在使用OO的這些部分,只是這些原則集中關注於依賴管理。

依賴管理是我們每個人都要面對的問題,每當我們在屏幕面前打開那些彼此糾結又令人作嘔的代碼,我們就會遭受不良的依賴管理所帶來的惡果。不良的依賴管理導致代碼難以改變,易被破壞,而且不可重用。實際上,我在PPP一書中談論過很多不同的設計壞味道,而這些都與依賴管理有關。從另一方面來說,如果依賴經過了良性的管理,代碼就可以保持靈活性、健壯性和重用性。所以依賴管理和這些相關原則是程序員們渴求的讓軟件保持優良架構的基石。

頭五項原則是關於類設計的,它們是:

SRP,單一職責原則,一個類應該有且只有一個改變的理由。

OCP,開放封閉原則,你應該能夠不用修改原有類就能擴展一個類的行爲。

LSP,Liskov替換原則,派生類要與其基類自相容。

DIP,依賴倒置原則,依賴於抽象而不是實現。

ISP,接口隔離原則,客戶只要關注它們所需的接口。

另外的六項是關於包的設計原則。在本文中,包是指一個二進制的可發佈文件,比如:jar文件、或dll文件,而不是Java包或是C++的命名空間。

頭三項包原則是關於包內聚性的,它們會告訴我們該把什麼劃分到包中:

REP,重用發佈等價原則,重用的粒度就是發佈的粒度。

CCP,共同封閉原則,包中的所有類對於同一類性質的變化應該是共同封閉的。

CRP,共同重用原則,一個包中的所有類應該是共同重用的。

最後的三項原則是關於包之間的耦合性原則的,並且論述了評價系統中包結構優良與否的評判標準

ADP,無環依賴原則,在包的依賴關係圖中不允許存在環。

SDP,穩定依賴原則,朝着穩定的方向進行依賴。

SAP,穩定抽象原則,包的抽象程度應該和其穩定程度一致。

譯註:

1,OOD,全稱Object Oriented Design,即面向對象設計。

2,PPP,即Bob大叔的著作《敏捷軟件開發 原則、模式與實踐》一書以及其相關書籍,因都有“原則、模式與實踐”,即Priciples, Patterns and Practices,故常簡稱爲PPP。

3,命名空間,原文爲namespace,也譯作名字空間。它是一種特殊的作用域,它包含了處於該作用域內的所有標示符,且本身也用一個標示符來表示,這樣便於將一系列在邏輯上相關的標示符用一個標示符來組織。就Java編程語言來說,命名空間是通過java包來表達的,所有代碼都歸屬與一個包。來自其他包中的代碼要通過指定包名來引用某項特定的標示符,例如,包java.lang中的String類要通過java.lang.String的形式引用。在C++中,命名空間常用來避免命名衝突,儘管現今的C++語言對命名空間做出了擴展,但過去的C++代碼很少使用此項功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章