Gregor Hohpe

好 API 的挑戰#

設計良好 API 的重要性和挑戰已經被討論了很多。API 很難第一次就做對,而且之後更難修改——有點像養小孩。大多數有經驗的程式設計師已經知道,好的 API 應該遵循一致的抽象層次(level of abstraction)、展現一致性(consistency)對稱性(symmetry),並為富有表達力的語言提供詞彙。然而,了解這些指導原則並不會自動轉化為適當的行為。

「方便」的陷阱#

作者特別挑出一種他經常遇到的 API 設計策略:以**方便(convenience)**為名的設計。這通常以下列「洞見」開始:

  • 「我不想讓其他類別為了做一件事而呼叫兩次」
  • 「為什麼要多做一個方法?它跟這個方法幾乎一樣,我加個 switch 就好」
  • 「很簡單嘛:如果第二個字串參數以 .txt 結尾,方法就自動假設第一個參數是檔名」

這些出於好意的做法往往會降低使用 API 的程式碼可讀性。例如:

parser.processNodes(text, false);

如果不查看實作或文件,這段呼叫幾乎毫無意義。這個方法很可能是為了實作者的方便而設計,而非為了呼叫者的方便

真正的解藥#

方便如果是用來對抗繁瑣、笨拙或尷尬,那本身並沒有錯。但如果我們仔細想想,真正的解藥是效率(efficiency)一致性(consistency)優雅(elegance),而不一定是方便。API 應該隱藏底層的複雜性,因此我們確實可以期望好的 API 設計需要花費一些心力。

API 即語言#

把 API 當作語言的隱喻可以引導我們做出更好的設計:

  • API 應該提供一個表達力豐富的詞彙,讓上層可以提出並回答有用的問題
  • 這不代表每個問題只能有一個方法——豐富的詞彙允許我們表達意義上的細微差別
  • 例如,我們偏好用 run 而不是 walk(true),即使它們本質上是同一操作
  • 一致且深思熟慮的 API 詞彙讓上層的程式碼更具表達力且易於理解

更重要的是,**可組合的詞彙(composable vocabulary)**讓其他程式設計師能以你未曾預料的方式使用 API——這才是對使用者真正的方便。

下次當你想把幾件事合併到一個 API 方法時,記住:英語中並沒有 MakeUpYourRoomBeQuietAndDoYourHomework 這個字,即使這是一個非常頻繁的操作。