
近期 Jetpack Compose 發布了 1.0 版本,帶來了一系列用於構建 UI 的穩定 API。今年早些時候,我們發布了 API 指南,介紹了編寫 Jetpack Compose API 的最佳實踐和 API 設計模式。經過多次迭代公共 API 接口 (API surface) 之後形成的指南,其實沒有展示出這些設計模式的形成過程和我們在迭代過程中決策背後的故事。
本文將繼續帶您了解一個 "簡單"的 Button 的 "進化之旅",來深入了解我們是如何迭代設計 API,使其簡單易用又不失靈活性。這個過程需要基於開發者的反饋,對 API 的可用性進行多次的適配和改進。
在上一篇文章中,我們通過開發者反饋、API 一致性和可發現性三個方面,和大家探討了 Button API 的迭代過程。本文將進一步為大家展示 Button API 是如何在原有設計上逐步優化演變成為今天的設計。

映射開發者的工作框架

△ material.io 中的 Material Button
我們從開發者活動中得到了一個關鍵啟示 —— 大多數開發者不太熟悉 Material Button 中的命名習慣。比如,很多開發者無法區分 ContainedButton 和 OutlinedButton:

更清楚地描述角色
研究發現,另外一個令人困惑的點是兩個已存在的 Button 的版本:一個 Button 可接受一個 String 類型的參數作為文本,而一個 Button 可接受一個可修改的 lambda 參數,表示通用內容。這麼設計的本意是從兩個不同的層次來提供 API:
帶有文本的 Button 更簡單一些,更加易於實現
更高級的 Button,它其中的內容更具開放性
單步代碼
緊耦合的副作用
支持工作框架
使用 "slot API" 解決問題
列舉上述問題後,我們決定去掉 Button 的原始類型重載,為每種 Button 僅留下包含針對內容的可組合 lambda 參數的 API。我們開始將這個通用的 API 形式叫做 "slot API",現已經廣泛應用於各個組件。
△ 帶有橫向排列的圖片和文本的 Button


展望未來
我們對 Button API 所做的修改數量之多,在討論Button 的會議中所付出的時間之多,以及收集開發者的反饋所投入的精力之巨大,足以驚人。話雖如此,我們對 API 整體的效果非常滿意。事後看來,我們看到在 Compose 中 Button 變得更具可發現性、可定製性,最重要的是它促進了組合式思維。
△1.0 Button AP
1.0 Button AP
https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/material/material/src/commonMain/kotlin/androidx/compose/material/Button.kt;l=96?q=Button.kt
重要的是認識到,我們的設計決策都基於下面這句口號:
*這裡出自著名的技術類書籍:英文版:《Learning Perl: Making Easy Things Easy and Hard Things Possible》(Randal L. Schwartz、Brian D Foy 和 Tom Phoenix 著),中文版:《Perl 語言入門》(盛春譯)
我們嘗試通過減少重載,並將 "樣式"扁平化處理,使開發變得更加簡單。與此同時,我們改進了 Android Studio 的自動補全功能,來幫助開發者提高效率。
這裡我們希望特別提出在整個 API 設計過程中的兩個要點:
API 的設計是一個迭代的過程。在 API 最初的迭代中就達到完美的狀態是幾乎不可能的。有一些需求容易被忽視。作為一個 API 的作者,您需要做出一些假設。這其中包括開發者背景的不同,所帶來的不同思維方式¹,最終影響了開發者探索和使用 API 的方式。適配調整是無法避免的,這是好事,不斷迭代可以得到可用性更高並且更加直觀的 API。
在迭代一個 API 設計時,您最有價值的工具之一是開發者使用 API 體驗的反饋循環。對我們的團隊來說,最關鍵的是去理解開發者所說的 "這個 API 太複雜了" 意味着什麼。當錯誤調用 API 時,通常會降低開發者的成功率和效率,從中所獲得感悟,會幫助我們更深入理解 "複雜 API"的意思。我們不斷迭代的關鍵驅動力是我們要設計易用且出色的 API。為此,創建開發者反饋循環,我們使用了多種研究路徑 —— 現場編程活動²,和需要開發者提供體驗日記³的遠程途徑。我們已經可以理解開發者是如何處理 API,以及他們為打算實現的功能,找到正確方法所採取的路徑。諸如工程師思維方式 (Programmer Thinking Styles) 和認知緯度 (Cognitive Dimensions) 這類框架中的支柱,有助於我們跨職能團隊保持語言思維上的一致,不僅表現在審核、溝通開發者反饋中,也涉及到 API 設計討論。尤其是,當評估用戶體驗和功能性之間的關係時,這個框架幫助我們塑造了為選擇和權衡所做的討論。
來自 Android Developer UX 團隊的 Meital Tagor Sbero 受到角色模型和思維方式 (personas & Thinking Styles) 的設計和認知維度框架 (Cognitive Dimensions Framework) 的啟發,開發了工程師思維方式框架 (Programmer Thinking Styles Framework)。該框架使用開發者在限定時間內所需 "解決方案的類型"的動機和態度,幫助開發者確定 API 可用性的設計思路。它兼顧了普通工程師的工作方式,並且針對高強度開發任務優化了可用性。
我們通常使用這種方式評估 API 特定方面的可用性。比如,每個活動會邀請一組開發者使用 Button API 來完成一系列開發任務,這些任務會特意暴露一些 API 的特徵,而這些特徵是我們希望收集反饋的目標。我們通過放聲思考法,來獲得更多關於開發者所追求的和開發者所設想的信息。這些活動中還包含研究者通過一些隨訪的問題,來進一步了解開發者的需求。我們會回顧這些活動,從而確定開發者在編程任務中促成成功或者導致失敗的行為模式。
我們通常使用這種方式來評估 API 在一段時間內的可用性和易學習性。這種方式可以通過傾聽開發者在常規工作中的反饋,來捕捉遇到困難的瞬間和受到啟發的瞬間。在這個過程中,我們會有一組開發者開發由他們自選的特定項目,同時也確保他們會使用我們希望評估的 API。我們會結合開發者通過自行提交的日記,和由研究人員基於認知維度框架 (Cognitive Dimensions Framework) (示例) 所組織的深度調查,以及專訪活動來幫助我們確定 API 的可用性。
Meital Tagor Sbero
https://www.linkedin.com/in/meitaltagor/
角色模型和思維方式 (personas & Thinking Styles)
https://medium.com/inclusive-software/tagged/thinking-styles
認知維度框架 (Cognitive Dimensions Framework)
https://www.researchgate.net/profile/Marian-Petre-4/publication/200085937_Usability_Analysis_of_Visual_Programming_Environments_A_%27Cognitive_Dimensions%27_Framework/links/02bfe50fbf23476730000000/Usability-Analysis-of-Visual-Programming-Environments-A-Cognitive-Dimensions-Framework.pdf
示例
https://arxiv.org/pdf/1703.09846.pdf
問題提出和建議反饋
https://issuetracker.google.com/issues/new?component=612128&template=1253476
Google 用戶體驗調研
推薦閱讀
點擊屏末|閱讀原文|即刻了解使用 Jetpack Compose 打造更出色的應用