如何設(shè)計一個優(yōu)秀的API

0 評論 6220 瀏覽 21 收藏 11 分鐘

摘要: 到目前為止,已經(jīng)負(fù)責(zé) API 接近兩年了,這兩年中發(fā)現(xiàn)現(xiàn)有的 API 存在的問題越來越多,但很多 API 一旦發(fā)布后就不再能修改了,即時升級和維護是必須的。一旦 API 發(fā)生變化,就可能對相關(guān)的調(diào)用者帶來巨大的代價,用戶 …

到目前為止,已經(jīng)負(fù)責(zé) API 接近兩年了,這兩年中發(fā)現(xiàn)現(xiàn)有的 API 存在的問題越來越多,但很多 API 一旦發(fā)布后就不再能修改了,即時升級和維護是必須的。一旦 API 發(fā)生變化,就可能對相關(guān)的調(diào)用者帶來巨大的代價,用戶需要排查所有調(diào)用的代碼,需要調(diào)整所有與之相關(guān)的部分,這些工作對他們來說都是額外的。如果辛辛苦苦完成這些以后,還發(fā)現(xiàn)了相關(guān)的 bug,那對用戶的打擊就更大。如果 API 經(jīng)常發(fā)生變化,用戶就會失去對提供方失去信心,從而也會影響目前的業(yè)務(wù)。

但是我們?yōu)槭裁催€要修改 API 呢?為了 API 看起來更加漂亮?為了提供更多功能?為了提供更好的性能?還是僅僅覺得到了改變了時候了?對于用戶來說,他們更愿意使用一個穩(wěn)定但是看起來不那么時髦的 API,這并不意味著我們不再改進 API 了。當(dāng)糟糕的 API 帶來的維護成本越來越大時,我想就是我們?nèi)ブ貥?gòu)它的時候。

如果可以回頭重新再做一遍,那么我心目中的優(yōu)秀的 API 應(yīng)該是怎么樣的?

判斷一個 API 是否優(yōu)秀,并不是簡單地根據(jù)第一個版本給出判斷的,而是要看隨著時間的推移,該 API 是否還能存在,是否仍舊保持得不錯。槽糕的 API 接口各種各樣,但是好的 API 接口對于用戶來說必須滿足以下幾個點:

而對于開發(fā)人員來說,要求又是不一樣的:

  • 易閱讀:代碼的編寫只需要一次一次,但是當(dāng)調(diào)試或者修改的時候都需要對代碼進行閱讀。
  • 易開發(fā):個最小化的接口是使用盡可能少的類以及盡可能少的類成員。這樣使得理解、記憶、調(diào)試以及改變 API 更容易。

如何做到以上幾點,以下是一些總結(jié):

1、?面向用例設(shè)計

如果一個 API 被廣泛使用了,那么就不可能了解所有使用該 API 的用戶。如果設(shè)計者希望能夠設(shè)計出被廣泛使用的 API,那么必須站在用戶的角度來理解如何設(shè)計 API 庫,以及如何才能設(shè)計出這樣的 API 庫。

2、?采用良好的設(shè)計思路

在設(shè)計過程中,如果能按照下面的方式來進行設(shè)計,會讓這個 API 生命更長久

  • 面向用例的設(shè)計,收集用戶建議,把自己模擬成用戶,保證 API 設(shè)計的易用和合理
  • 保證后續(xù)的需求可以通過擴展的形式完成
  • 第一版做盡量少的內(nèi)容,由于新需求可以通過擴展的形式完成,因此盡量少做事情是抑制 API 設(shè)計錯誤的一個有效方案
  • 對外提供清晰的 API 和文檔規(guī)范,避免用戶錯誤的使用 API,尤其是避免 API(見第一節(jié))靠后級別的 API 被用戶知曉與誤用

除此之外,下面還列出了一些具體的設(shè)計方法:

  • 方法優(yōu)于屬性
  • 工廠方法優(yōu)于構(gòu)造函數(shù)
  • 避免過多繼承
  • 避免由于優(yōu)化或者復(fù)用代碼影響 API
  • 面向接口編程
  • 擴展參數(shù)應(yīng)當(dāng)是便利的
  • 對組件進行合理定位,確定暴露多少接口
  • 提供擴展點

3、?避免極端的意見

在設(shè)計 API 的時候,一定要避免任何極端的意見,尤其是以下幾點:

  • 必須漂亮(API 不一定需要漂亮)
  • API 必須被正確地使用(用戶很難理解如何正確的使用 API,API 的設(shè)計者要充分考慮 API 被誤用的情況:如果一個 API 可能會被誤用,那么它一定會被誤用)
  • 必須簡單(我們總會面臨復(fù)雜的需求,能兩者兼顧的 API 是更好的 API)
  • 必須高性能(性能可以通過其他手段優(yōu)化,不應(yīng)該影響 API 的設(shè)計)
  • 必須絕對兼容(盡管本文一直提到如何保證兼容,但是我們?nèi)匀灰庾R到,一些極少情況下會遇到的不兼容是可以容忍的)

4、?有效的 API 評審

API 設(shè)計完成以后,需要經(jīng)過周密的設(shè)計評審,評審的重點如下:

  • 用例驅(qū)動,評審前必須提供完善的使用用例,確保用例的合理性和完備性。
  • 一致性,是否與系統(tǒng)中其他模塊的接口風(fēng)格一致,是否與對稱接口的設(shè)計一致。
  • 簡單明了,API 應(yīng)該簡單好理解,容易學(xué)習(xí)和使用的 API 才不容易被誤用,給我們帶來更多的麻煩。
  • API 盡可能少,如果一個 API 可以暴露也可以不暴露,那么就不要暴露他,等到用戶真正有需求的時候再將它成為一個公開接口也不遲。
  • 支持持續(xù)改進,API 是否能夠方便地通過擴展的方式增加功能和優(yōu)化。

5、?提高 API 的可測試性

API 需要是可測試的,測試不應(yīng)依賴實現(xiàn),測試充分的 API,尤其是經(jīng)過了嚴(yán)格的“兼容性整合測試”的 API,更能保證在升級的過程中不出現(xiàn)兼容性問題。兼容性整合測試,是指一組測試用例集合,這組測試用例會站在使用者的立場上使用 API。在 API 升級以后,再檢測這組測試用例是否能完全符合預(yù)期的通過測試,盡可能的發(fā)現(xiàn)兼容性問題。

6、?保證 API 的向后兼容

對于每一個 API 的設(shè)計者來說,都渴望做到“向后兼容”,因為不管是現(xiàn)在的 API 用戶,還是潛在的 API 用戶,都只信任那些可兼容的 API。但向后兼容有多個層次上的意義,而且不同層次的向后兼容,也意味著不同的重要性和復(fù)雜度。

7、?保持逐步改善

過去我們總希望能將現(xiàn)有的“不合理”的設(shè)計完全推翻,然后按照現(xiàn)在“美好”的思路,重新設(shè)計這個 API,但是在一段時間以后,又會碰到一樣的狀況,需要再推翻一次。 如果我們沒有有效的逐步改善的辦法,依靠推翻現(xiàn)有設(shè)計,重新設(shè)計 API 只能讓我們回到起點,然后重現(xiàn)之前的過程。 要有一套行之有效的持續(xù)改善的辦法來在 API 兼容的同時,改善 API 使之更好。

8、?把握 API 的生命周期

每一個 API 都是有生命周期的,我們需要讓 API 的生命周期更長,并且在 API 的生命周期結(jié)束時能讓其平滑的消亡。

  • 告訴用戶我們是如何設(shè)計的,避免誤用,提供指導(dǎo),錯誤的使用往往是縮短 API 壽命的一大殺手
  • 提供試用期,API 不可能一開始就是穩(wěn)定,經(jīng)過試用的 API 才能有更強的生命力
  • 為 API 分級:內(nèi)部使用;二次開發(fā)使用;開發(fā)或試用中;穩(wěn)定;棄用 API。避免 API 被濫用的同時,我們可以通過調(diào)整 API 的級別,來擴大其影響力,也能更優(yōu)雅的結(jié)束一個 API 的生命周期。

開發(fā) API 的過程其實就是一個溝通交流的過程。溝通的雙方就是 API 用戶和 API 設(shè)計者。

9、?一些具體的實施方案

在一個 API 不可避免要消亡或者改變的時候,我們應(yīng)該接受并且面對這個事實,下面列舉了幾種保證兼容性的前提下,對 API 進行調(diào)整的辦法:

  • 將 API 標(biāo)記為棄用,重新建立一個新的 API。如果一個 API 不可避免要被消亡,這是唯一的辦法。
  • 為其添加額外的參數(shù)或者參數(shù)選項來實現(xiàn)功能添加
  • 將現(xiàn)有 API 拆成兩部分,提供一個精簡的核心 API,過去的 API 通過封裝核心 API 上實現(xiàn)。這通常用于解決用戶需要一個代碼精簡的版本時。
  • 在現(xiàn)有的 API 基礎(chǔ)上進行封裝,提供一個功能更豐富的包或者類

 

來源:apkbus

更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發(fā)揮!