我們對自己與之互動的所有東西的可用性都有相同的預期,包括 UI 和 API。所以,我們用於 UI 的指導原則也可以被轉化到 API。我們在前一篇文章中已經看到了前面五條指導原則。現在,是時候看看剩下的了。
開發者也是使用者 — 第一部分
_改善 UI 和 API 可用性的五條指導原則_medium.com
6. 識別而不是回憶
UI: 識別出熟悉的事物所耗費的認知代價是最小的,並且它還能被上下文環境所觸發。回憶意味著從記憶中取出細節,它需要多很多的時間。從一系列選項中選擇,比根據記憶寫出選項容易很多。一個使用常見 icon 的簡單 UI 是基於識別的,一個命令列介面是基於回憶的。資訊和功能應該被設計得明顯,符合直覺並且容易使用。
鉛筆 icon 是一個表示編輯的符號,容易識別,與 app 無關。
使名稱清晰、易於理解
A 變數 名稱應該說明它代表什麼,而不是如何使用: isLoading
, animationDurationMs
.
A 類 名稱應該是一個名詞,說明它代表什麼:RoomDatabase
, Field
.
A 方法 名稱應該是一個動詞,說明它做什麼:query()
, runInTransaction()
.
7. 使用的靈活性和效率
UI: 你的應用可能被沒有經驗和經驗豐富的使用者同時使用。建立一個 UI使其迎合這兩種使用者的需求,並讓他們習慣常用的操作。據說,20% 的功能被 80% 的使用者使用。你需要在簡潔和功能之間權衡。找出你的 app 中的那 20%,然後把它們變得儘可能簡單易用。使用 逐步展現原則 ,讓其他使用者在次要的頁面使用進階功能。
Wi-Fi 設定預設顯示基本選項,但也包含進階選項。它適合使用者的需求。
寫有彈性的 API
使用者應當能夠使用 API 高效地完成任務,因此 API 需要有彈性。比如,在查詢資料庫時,Room 提供不同的返回值,允許使用者進行同步查詢,使用LiveData,或者如果他們喜歡的話,使用 RxJava2 中的 API。
@Query(“SELECT * FROM Users”)
// synchronous
List<User> getUsers();
// asynchronously
Single<List<User>> getUsers();
Maybe<List<User>> getUsers();
// asynchronously via observable queries
Flowable<List<User>> getUsers();
LiveData<List<User>> getUsers();
複製程式碼
把相關的方法放在相關的類中
如果一個類和一個開發者寫出的程式碼沒有直接關係,那麼他通常很難找到其中的某個方法。而且,通常包含大量有用方法的 Util 和 Helper 類會很難找到。在使用 Kotlin 時,解決這個問題的方案是使用 擴充套件函式。
8. 美觀和極簡的設計
UI: UI 應當保持簡單,只包含當時和使用者相關的資訊。不相關或很少使用的資訊應當被刪除或者移到其它螢幕,因為它們的存在使使用者分心,並且減少了相關資訊的重要性。
Pocket Casts app 使用極簡設計
這個播客 app 的集列表頁面顯示最少量的,和上下文相關的資訊:如果使用者沒有下載某集,這一集的大小和下載頁面是可見的;如果使用者已經下載,就可以見到時長和播放按鈕。同時,對於那些好奇的使用者而言,詳情頁面包含所有這些資訊,並且不止於此。
API: 使用者們有一個目標:用你的 API 更快解決問題。所以把它們的路徑做得儘可能短和直接。
不要暴露內部 API 邏輯
API: 不必要地暴露 API 內部邏輯會讓你的使用者困惑,並降低你的 API 的可用性。不要暴露不必要的方法和類。
不要讓使用者做任何 API 能夠做的事情
API: 從 22.1.0 開始,Android Support Library 提供 RecyclerView
相關的一系列物件,使使用者可以基於頻繁改變的大型資料集建立 UI 元素。當列表改變時,RecyclerView.Adapter
需要被通知哪些資料被更新了。這使得開發者創造他們自己的用於比較列表的方法。在 25.1.0 版本的 Support Library, 這類反覆出現的程式碼被 [DiffUtil](https://developer.android.com/reference/android/support/v7/util/DiffUtil.html)
類極大簡化了。而且,DiffUtil
使用經過優化的演算法,減少你需要寫的程式碼量並且增強效能。
9. 幫助使用者識別、診斷並擺脫錯誤
UI: 向你的使用者提供有助於識別、診斷並擺脫錯誤的錯誤資訊。好的錯誤資訊明確指出有東西出錯了,使用禮貌而易讀的語言準確描述問題,包含有助於解決問題的建議。避免顯示狀態碼或者異常類名稱,使用者不會知道如何處理這些資訊的。
建立事件時的錯誤資訊。 來源
在輸入區域失去焦點時儘快顯示錯誤資訊,不要等到使用者點選提交表單的按鈕。更不要等到服務端傳來錯誤資訊。使用 TextView 的功能 來顯示錯誤資訊。如果你在建立一個事件表單,你要通過直接給 UI 控制元件設定限制的方法,防止使用者建立發生在過去的事件。
快速失敗
API: 一個 bug 被報告得越早,它就會造成越少的損失。因此,失敗的最好時機就是在編譯期。例如,Room 會在編譯期報告任何不正確的查詢或者類註解。
如果你不能在編譯期失敗,最好儘快在執行時失敗。
異常應當用於指示異常的情況
API: 使用者不應當使用在控制流中使用異常。異常應當僅用於例外情況,或者 API 的不正確使用。儘可能使用返回值來指示這些情況,因為捕獲並處理異常幾乎總是比測試返回值要慢。
例如,試圖把 null
值插入一個有 NON NULL
限制的列中,就是一種異常的情況,會丟擲 SQLiteConstraintException
。
丟擲具體的異常。儘量使用已有的異常
API: 開發者知道 IllegalStateException
和 IllegalArgumentException
是什麼意思,哪怕他們不知道你的 API 中發生了什麼。通過丟擲已有的異常來幫助你的 API 使用者,使用盡量具體而不是籠統的異常,並好好填寫錯誤資訊。
在通過 [createBitmap](https://developer.android.com/reference/android/graphics/Bitmap.html#createBitmap%28android.graphics.Bitmap,%20int,%20int,%20int,%20int%29)
方法建立 Bitmap
時,你需要提供新 bitmap 的寬高等資訊。如果你傳入小於 0 的值作為引數,這個方法將會丟擲 IllegalArgumentException
。
錯誤訊息應當準確指示問題
API: 為 UI 寫錯誤資訊的指導原則,也適用於 API。提供細緻的錯誤資訊,以幫助使用者修復他們的程式碼。
比如,在 Room 中,如果一個查詢在主執行緒執行,使用者將會獲得 java.lang.IllegalStateException: 不能在主執行緒訪問資料庫,因為它有可能把 UI 鎖住較長的一段時間
。這表明查詢被執行時的狀態(在主執行緒)是不合法的。
10. 幫助和文件
UI: 你的使用者應當能夠不用文件使用你的應用。對於非常複雜或者領域專門化的 app,這也許是不可能的。所以,如果需要文件,確保它易於尋找、易於使用,並解答了常見的問題。
諸如 “幫助” 或者 “傳送反饋” 之類的元素通常在導航選單底部
API 應當是自說明的
API: 好的方法、類和成員命名使 API 能夠闡明自身的意義。但無論 API 多好,沒有好的文件就無法被使用。這就是每個 public 的元素——方法,類,域,引數——應當用文件說明的原因。對於你,一個 API 開發者來說簡單易見的東西,也許對於你的 API 使用者來說就不那麼容易和顯然了。
示例程式碼應該是模範程式碼
API: 示例程式碼有若干用途:他們幫助使用者理解 API 的目的,用途,以及上下文。程式碼片段 用於解釋如何使用基本的 API 功能。 教程 教使用者關於 API 特定層面的知識。程式碼示例 是更加複雜的例子,通常是一整個應用。這三者之中,缺少程式碼示例會引起最嚴重的問題,因為開發者看不到整體圖景——你所有的方法和類是如何協作的,以及它們是如何與系統協作的。
如果你的 API 流行起來了,有可能會有數以千計的開發者使用這些例子。他們將會成為如何使用你的 API 的例子。因此,你犯的每個錯誤都會讓你自食其果。
這些年,我們學習了很多關於 UI 可用性的知識;我們知道使用者們需要什麼,以及他們在想什麼。他們需要符合直覺、高效、正確的 UI,並且要能幫助他們用合適的方式完成特定任務。這些概念都不止於 UI,還適用於 API,因為開發者也是使用者。所以,讓我們通過可用的 API 幫助他們(也是幫助我們自己)吧。
API應當易用且不易濫用——它應該易於做簡單的事,可能做複雜的事,不可能——至少難以——做錯誤的事 Joshua Bloch — source
參考文獻
- 10 Usability Heuristics for User Interface Design
- www.apiusability.org/
- Myers, B. A., & Stylos, J. (2016). Improving API usability. Communications of the ACM, 59(6), 62–69. PDF
- Bloch, J. (2006). How to design a good API and why it matters. Companion to the 21st ACM SIGPLAN symposium on Object-oriented programming systems, languages, and applications. ACM. PDF
- Ellis, B., Stylos, J., & Myers, B. (2007). The factory pattern in API design: A usability evaluation. Proceedings of the 29th international conference on Software Engineering. IEEE Computer Society. PDF
- Robillard, M. P. (2009). What makes APIs hard to learn? Answers from developers. Software, IEEE, 26(6), 27–34. PDF
- Scheller, T., & Kühn, E. (2015). Automated measurement of API usability: The API Concepts Framework. Information and Software Technology, 61, 145–162. PDF
- Preventing User Errors: Avoiding Conscious Mistakes
- Error Message Guidelines
- Material Design Patterns and Guidelines
感謝 Nick Butcher 和 Tao Dong.
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。