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 這個字,即使這是一個非常頻繁的操作。