Java 接口規範與最佳實踐

  • 可理解

  • 文檔完善

  • 格式統一:這裏涉及很多方面,包括:接口返回類型、命名規則以及參數順序

    • 在我們所有的API方法中,要麼是全是getXYZ()格式,要麼全是xyz(),最好不要兩種格式都有。
    • 假設我們有方法重載,原始方法接受參數Object...,重載方法接受參數爲Collection<? extends Object>,那麼,重載方法不能部分可見
  • 恰到好處的適用:作爲一名開發人員,很自然的一種本能就是儘可能的開發提供大而全的服務接口,但這樣做可能會帶來兩個問題:1. 接口過於笨重,接口調用方可能需要額外消化一些不必要的業務邏輯來理解接口實際含義。2. 接口暴露越多,維護負擔越重。因此,所謂恰到好處的適用就是這個含義:

    • 接口應功能單一,並且能正確響應
    • 瞭解接口潛在用戶及目標
  • 一定範圍、時期的使用受限:我們都知道開發接口非常容易,但事情遠非一蹴而就那麼簡單,接口背後帶來的是服務承諾。接口的服務成本依賴於很多因素:項目的實際情況以及社區本身,比如,有些項目可能非常樂於變更,但有些項目(比如JDK)則期待儘量保持穩定,這是兩種極端狀態,但,對於絕大部分項目來說,基本上都處於中間狀態,慣例做法是通過一種語義化的版本管理方式實現接口的持續演變,即在接口從主版本更新刪除之前,首先進行廢棄處理(即我們常見的deprecate標識)。對於某些少部分項目來說,他們處理的方式更加多樣,項目中會包含多種接口標識:比如:實驗性版本的、Beta版本的、預覽功能性的,這麼做的目的是在最終接口確定之前,可以真實的收到各種版本接口的真實使用反饋,通常做法是在這些不同的版本接口上添加@Deprecated註解,當最終的服務接口確認發佈之後,再刪除這些中間服務接口。

  • 可變的:對於我們對外暴露的每一個接口,這都是一種服務承諾,既然是承諾,那麼都有可能未來讓我們自己爲難或者尷尬的境地,所以,我們必須以發展前瞻的眼光來審視未來可能的SDK版本更新中更廣泛的上下文環境中對接口所帶來的影響。

  • 防止信息泄漏:避免接口實現類或者外部依賴類通過公共接口暴露出去(所謂暴露出去可能有兩種方式:作爲返回類型、作爲參數類型),通常有以下兩種方式來避免信息泄露:

    • 所有實現類均置於impl包中,此包下的所有類均不會出現在JavaDoc中,如果接口基於JDK1.9或者以上的版本開發,可以通過模塊的方式排除目標類集合
    • 確保所有實現類的訪問修飾符爲package-private,即類定義不包含任何訪問修飾符。
  • 正確理解protected含義:Java中的protected關鍵字經常被誤用或者說濫用,簡單來說,protected主要用於子類之間,而public則主要用於對外接口。事實上protected關鍵字會影響接口類的行爲,進而導致本不應暴露的內部私有方法暴露成protected或者public類型。

  • 刻意繼承:當我們在開發一個接口時,我們必須在功能性、靈活性和未來的可發展性、可持續性之間作一個平衡,一種常見的做法是使用final關鍵字,一旦標識一個方法或者類爲final類型,我們就是要明確的告訴開發人員,不要去擴展或者重寫這些特殊的類或者方法。final關鍵字對我們非常有用,畢竟我們的接口並非十全十美,與其受困於在老的版本中不停的解決問題,還不如另闢蹊徑升級接口補丁,這樣的話,我們只會引入新的問題,理想情況下,當接口調用方發現final標識,他們甚至可以直接與接口方直接溝通討論,直至達到更加完美的接口服務方案,final關鍵字可以在後續的正式發佈版本中剔除,但不建議在已經發布的接口中使用final關鍵字。

  • 向後兼容:在我們的日常接口實踐中,當我們遇見新的需求或者問題時,好的做法是新增一個接口,但不推薦刪除或者修改現有的接口。這麼做的主要目的是向後兼容,這也很容易理解,當我們刪除或者修改一個現有接口時,在用戶升級至下個發佈之前,我們其實就隱含帶來了破壞用戶原有代碼正常調用的風險。但有時候,我們需要實現接口向後不兼容(比如,原有接口設計錯誤),一般我們可以使用@Deprecated,但通常的做法是使用semantic versioning策略。

  • 正確的使用Optional:JDK1.8引入的Optional關鍵字爲我們減少NPE錯誤提供了一種可能,當方法返回爲Optional它可以確保返回值不爲NULL,那麼在這種場景下,就需要由調用方來確認返回值中是否包含元素或者爲空。但注意:

    • 不要返回Optional<Collection<T>>,這種可以簡潔的以Collection<T>形式來表示
    • 不要在返回類型爲Optional的方法中返回null
  • 不要返回null值billion-dollar mistake,在Java中較之null返回值,針對不同的返回類型,我們都有更好的選擇:

RETURN TYPE NON-NULL RETURN VALUE
String “” (An empty string)
List / Set Map / Iterator Use the Collections class, e.g. Collections.emptyList()
Stream Stream.empty()
Array Return an empty, zero-length array
All other types Consider using Optional (but read the Optional section below first)

https://dzone.com/refcardz/java-api-best-practices?chapter=1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章