首頁>技術>

1 引言

優秀的 API 之於程式碼,就如同良好內涵對於每個人。好的 API 不但利於使用者理解,開發時也會事半功倍,後期維護更是順風順水。

一個骨灰級資深的同事跟我說過,任何在成長的程式碼庫,至少半年到一年就要重構一次,否則失去的不僅是活力,更失去了可維護性與可用性。

2 內容概要

由於本文已經是翻譯後的文章,概要只列出不涉及 c++ 概念的思路框架,細節請移步譯文。

好 API 的 6 個特質

極簡且完備、語義清晰簡單、符合直覺、易於記憶和引導 API 使用者寫出可讀程式碼。

靜態多型

儘量減少繼承,讓相似的類具備相似的 API,而不是統一繼承一個父類。因為統一繼承會帶來 API public 數量過多,父級無意義的方法對使用者產生誤導。

基於屬性的 API

屬性指的是物件狀態,透過屬性為粒度的 API,有利於使用者理解 API 的含義,但需注意關聯屬性的順序性。

API 語義和文件

比如傳值 -1 的含義是什麼?如果 API 文件不像 http status codes 一樣健全,建議透過列舉的方式增加可讀性。

命名的藝術

不要使用縮寫,保持一致性。類命名以功能分組作為字尾,比零散命名更易懂。

函式命名要體現出是否包含副作用,引數過多時以物件作為傳參,布林引數改為列舉型別,或者分解為兩個語義化 API。

3 精讀

以下精讀是對原文觀點的補充。

Const 入參

eslint 有一條規則,不要直接改變入參的值。這個規則的初衷是解決函式副作用問題,禁止可能產生副作用程式碼的產生。但卻可以透過如下方式避免:

function (num) {  let scopeNum = num  scopeNum = 5}

這是從包含指標型別程式語言學習過來的,因為當 *num 表示指標時,代表程式碼可能產生副作用(修改入參的風險)。而 js 並不總是這樣的,不但沒有指標申明,基本型別也總是透過複製進入傳參,非基本型別透過引用傳遞,也就是會發生透過如上程式碼繞過檢測,卻依然產生副作用(改變函式入參)的情況。

為了避免副作用,建議引入 flow 或 typescript,透過 const 關鍵字與約定約束入參行為:

function (const num) {  ...}

將沒有副作用函式的所有入參定義為 const 型別,靜態檢查階段就禁止了對值得直接修改,同時因為有這個關鍵字的約束,在函式體內也約定不要透過引用淺複製修改它的值。

但這也無法徹底避免,仍然可以透過如下寫法繞過檢測,修改入參:

function (const num) {  const scopeNum = { ...num }  scopeNum.a.b = 'c'}

在 js 中沒有完美的方式避免對入參的修改,但透過對入參修飾 const 關鍵字,可以對使用者明確這是純函式,對開發者提示不要寫有副作用的程式碼。

c++ 的 const 定義從編譯開始就完全杜絕了修改的可能性,雖然有 const_cast “去” const 行為,但仍然不會改變入參的值(雖然可以後續對值修改,指標指向保持不變,但用 const 修飾的入參值永遠不會改變)。

統一關鍵字型檔

所有 api 定義之前,先抽離業務和功能語義的關鍵字,統一關鍵字型檔; 可以更好地讓多人協作看起來如出一轍, 而且關鍵字型檔 更能夠讓呼叫者感覺到 符合直覺、語義清晰; 關鍵字型檔也是專案組新同學 PREDO 的內容之一, 很有帶入感;

單一職責

介面設計儘量要做到 單一職責,最細粒度化; 可以使用組合的方式把多個解耦的單個介面組合在一起作為一個大的功能項介面; 介面設計的單一職責,也更方便多人協作時候的擴充套件和組合;

面向未來的多型

對於介面引數的擴充套件,我們要做到面向擴充套件開放,面向修改關閉; 升級做到要相容,否則會導致大批次的下游不可用。

同時也要避免過度設計,當抽象功能只有一處使用時,儘量不要過早抽象。

不要重複區域性命名
class User {  // good  setName() {}    // bad  setUserName() {}}

在有上下文環境的呼叫中,減少不必要的描述可以提高 API 的精簡和清晰度。

const { setName } = this.props.store.userconst { setVisible } = this.props.store.article

上述 setName setVisible 脫離了 user article 作用域,當隔著幾百行呼叫時,早已不知所云。

4 總結

參考優秀類庫是設計 API 很好的方法之一,比如本文 c++ 參考的 Qt、js 可以參考 jQuery。

當 API 穩定後,需要花時間整理文件,因為寫文件的思考過程可能推動著你重構和最佳化程式碼。

最後,如果有精力,最好每半年重構一次(然後完整跑一遍測試)!

17
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • MySQL資料庫入門(四)