java中的類的設計原則
來源–———>java語言程式設計(基礎篇)(樑勇著,戴開宇譯)
在不斷的學習java過程中,下面的問題會一直存在,類似一些高內聚、低耦合、java設計原則都要牢記,設計類、抽象類、介面的能力,鍛鍊這種能力可以通過去檢視eclipse裡面的原始碼和自己多動手設計體驗一些經典類的設計過程,會有一部分的提升。當然,前提是必須瞭解一些關於類設計原則方面的知識。然後讓這些知識和實際程式碼結合起來,不停的去鍛鍊這種能力,會提升比較迅速。堅持!
類的設計原則有助於設計出合理的類。
內聚性
類應該描述一個單一的實體,而所有的類操作應該在邏輯上相互配合,支援一個一致的目的。例如:可以設計一個類用於學生,但不應該將學生與教職工組合在一個類中,因為學生和教職工是不同的實體。
如果一個實體擔負太多的職責,就應該按各自的職責分成幾個類。例如:String類、StringBuffer類和 StringBuilder類用於處理字串,但是他們的職責不同。String類處理不變的字串,StringBuilder類建立可變字串, StringBuffer()
與 StringBuffer() 類還包含更新字串的同步方法。一致性
遵循標準java程式設計風格和命名習慣。為類、資料域和方法選取具有資訊的名字。通常的風格是將資料宣告置於構造方法之前,並且將構造方法置於方法之前。
選擇名字要保持一致。給類似的操作選擇不同的名字並非良好的實踐。例如:Length() 方法返回String、StringBuilder 和 StringBuffer 的大小。如果在這些類中給這個方法用不同的名字就不一致了。
一般來說,應該具有一致性地提供一個公共無參的建構函式,用於構建預設例項。如果一個類不支援無參的建構函式,要用文件寫出原因。如果沒有顯示定義構造方法,即假定有一個空方法體的公共預設無參構造方法。
如果不想讓使用者建立類的物件,可以在類中宣告一個私有的構造方法,Math類就是如此。
封裝性
一個類應該使用private修飾符隱藏其資料,以免使用者直接訪問它。這使得類更易於維護。只在希望資料域可讀的情況下,才提供get方法;也只在希望資料域可更新的情況下,才提供set方法。例如:Rational類為numerator和denominator提供了get方法,但是沒有提供set方法,因為Rational物件是不可改變的。
清晰性
為使設計清晰,內聚性、一致性和封裝性都是很好的設計原則。除此之外,類應該有一個很清晰的合約,從而易於解釋和理解。
使用者可以以各種不同的組合、順序,以及在各種環境中結合使用多個類。因此,在設計一個類時,這個類不應該限制使用者如何以及何時使用該類;以一種方式設計屬性,以允許使用者按值的任何順序和任何組合來設定;設計方法應該使得實現的功能與他們出現的順序無關。例如:Loan類包含屬性loanAmount、numberOfYears和annualIntereRate,這些屬性的值,可以按任何順序來設定。
方法應在不生產混淆的情況下進行直觀定義。例如:String類中的substring(int beginIndex, int endIndex)方法就有一點混亂。這個方法返回從beginIndex到endIndex-1而不是endIndex的子串。該方法應該返回從beginIndex到endIndex的子字串,從而更加直觀。
不應該宣告一個來自其他資料域的資料域。例如,下面的Person類有兩個資料域:birthDate和age。由於age可以從birthDate匯出,所以age不應該宣告為資料域。
public class Person{
private java.util.Date.birthDate;
private int age;
}
完整性
類是為許多不同使用者的使用而設計的。為了能在一個廣泛的應用中使用,一個類應該通過屬性和方法提供多種方案以適應使用者的不同需求。例如:為了滿足不同的應用需求,String類包含了40多種很實用的方法。
例項和靜態
依賴於類的具體例項的變數或方法必須是一個例項變數或者方法。如果一個變數被類的所有例項所共享,那就應該將它宣告為靜態的。如果方法不依賴於某和具體的例項,那就應該將他宣告為靜態方法。
應該總是使用類名(而不是引用變數)引用靜態變數和方法,以增強可讀性並避免錯誤。
不要在構造方法中傳入引數來初始化靜態資料域。最好使用set方法改變靜態資料域。
構造方法永遠都是例項方法,因為它是用來建立具體例項的。一個靜態變數或方法可以從例項方法中呼叫,但是不能從靜態方法中呼叫例項變數或方法。
繼承和聚合
繼承和聚合之間的差異,就是 is-a(是一種) 和 has-a(具有)之間的關係。例如,蘋果是一種水果;因此,可以使用繼承來對Apple類和Fruit類之間的關係進行建模。人具有名字;因此,可以使用聚合來對Person類和Name類之間的關係建模。
介面和抽象類
介面和抽象類都可以用於為物件指定共同的行為。如何決定是採用介面還是類呢》通常,比較強的is-a (是一種)關係清晰的描述了父子關係,應該採用類來建模。例如,因為橘子是一種水果,他們的關係就應該採用類的繼承關係來建模。弱的is-a關係,也成為is-kind-of (是一類)關係,表示一個物件擁有某種屬性。弱的is-a關係可以使用介面建模。例如所有的字串都是可以比較的,因此String類實現了Comparable介面。圓或者矩形是一個幾何物件,因此Circle可以設計為GeometricObject的子類。圓有不同的半徑,並且可以基於半徑比較,因此Circle可以實現Comparable介面。
介面比抽象類更加靈活,因為一個子類只能繼承一個父類,但是卻可以實現任意個數的介面。然而,介面不嗯能夠具有具體的方法。可以結合介面和抽象的優點,建立一個介面。使用一個抽象類來實現它。可以視其方便使用介面或者抽象類。