Java面向對象設計最佳實踐 - 方法設計(二)

    這篇文章介紹方法範圍設計,這種設計是API開發人員容易忽視的部分,也是相對困難和耗時的。 所謂範圍,這裏分爲兩個方面:第一,物理範圍;第二,邏輯範圍。

1.什麼是物理範圍
主要是指訪問範圍。Java編程語言提供了4種訪問限定修飾符:public、protected、(package public)、private,這四個訪問限定符的訪問權限角度逐漸遞減。這些修飾信息保存在類的字節碼中,可以通過編譯時確定和驗證,這也是稱爲物理 範圍的原因。

2.什麼是邏輯範圍
如果說物理範圍限於訪問範圍的話,那麼邏輯範圍更加廣闊,包括方法返回類型、參數類型、參數數量等。具體的介紹在下篇詳細解釋。

3.怎麼設計範圍
通過簡單的解釋兩種範圍的意義,那麼下面關注怎麼來設計範圍。好的設計應該充分地發揮面向對象的複用特性。那麼滿足了複用特性的API設計就是好的設計 嗎?不一定。在面向對象設計原則中,常常掛在嘴邊的“高內聚、低耦合”,爲了降低耦合性,應該使API之間儘可能的少了解。

例如:測量人體重的輔助類-PersonWeightCalculator,其中定義了calculate方法,傳遞一個Person對象作爲參數,返回 double類型單位的重量值。按照業務邏輯的規定,需要了解人的性別,身高。設計中PersonWeightCalculator必須能訪問 Person的gender和height的狀態信息,在可能的情況中,還能訪問其他無關的Person的屬性信息,比如name信息。那麼,這種情況就 是一種不好的“暴露”設計。留下的問題是怎麼修改?
有人可能會說,既然PersonWeightCalculator耦合了Person對象,那麼把Person參數替換成兩個參數height和 gender。這樣減少了Person類型依賴,同時,也是“API之間知道最小化”。其實,這不是一個很好的方法,儘管不少API開發人員是這麼做的。 主要缺點有兩個:第一,破壞了“源代碼兼容性”。良好的API設計應該注意兼容性,其中有“源代碼”和“二進制”兼容性。所謂的“源代碼兼容性”是指,在 API的修正和增進前後,API的方法簽名或者其他定義保證語法和語義的兼容。反之,則是不兼容。回到例子中,通過修改方法列表,其他調用其的地方,都需 要作出相應的修改,否則編譯時錯誤。可以通過“開閉原則“(對增加開放,對修改關閉)來解決,添加一個新的帶height和gender參數的 calculate方法,標記原來方法爲Deprecated;第二,參數數量的問題,當前的算法只需要兩個參數,那麼怎麼擴展?還是添加一個新的方法? 當然可以這麼做,不過只依賴Person對象有何不可?賣一點關子,這個內容在下篇詳細介紹。

筆者的做法是,如果有必要的話,把PersonWeightCalculator類重構到Person類同包下。改變包的組織結構,對於其他調用者來說, 僅僅需要通過IDE重構功能重新導入即可,不需要改變實現代碼。然後,開放height和gender屬性爲package public。這樣做的好處是,只改變需要Person的屬性的開放性,不修改業務邏輯。這樣避免了修改後的風險,同時測試用例也不需要修改測試邏輯。

在JDK的API中,有不少的這樣做法,比如java.lang.ThreadLocal和java.lang.Thread。

  總之,方法範圍設計是很困難,不但需要很好地把握編程語言,而且全局地思考、設計和實現。這是一個過程,需要大量的時間,思考和學習,還有實踐。

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