開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

Android_開發者發表於2018-01-22

在前一篇文章中,我們探討了 UI 可用性與 API 可用性的重要性,並說明了 UI 可用性原則可以應用於 API。下面是前文連結:

開發者也是使用者 - 簡介 可用性 - 學於 UI,用於 API

在本文中,我們將具體討論前 5 條可用性方針:

  1. 系統狀態的可見性
  2. 讓系統符合真實世界
  3. 為使用者提供自由的操作方式
  4. 一致性與標準
  5. 預防錯誤的發生

1. 系統狀態的可見性

系統應當在合理的時間,通過合適的反饋,讓使用者瞭解它正在做什麼。

**UI:**當使用者進行一項需要耗費較長時間的操作時,應告知使用者操作的進度。例如,在載入圖片時顯示一個進度條,在上傳下載檔案時顯示百分比。應當讓使用者知道正在讓他們等待的是什麼,需要花多長時間。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

上圖:告知使用者當前狀態。圖片來源

**API:**API 應當提供某種可以查詢當前狀態的方式。例如,AnimatedVectorDrawable 類提供了一個方法來檢查動畫是否正在執行:

boolean isAnimationRunning = avd.isRunning();
複製程式碼

API 可以採用回撥機制來給出反饋,讓 API 使用者知道物件在何時改變了狀態 —— 類似於動畫開始與結束時的通知。例如,AnimatedVectorDrawable 物件可以 registering 一個 AnimationCallback 來完成上述操作。

2. 讓系統符合真實世界

應用程式應當“說”使用者的語言,使用使用者熟悉的短語和概念,而不應該使用面向系統的術語。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

上圖:使用使用者熟悉的概念。圖片來源

類與方法的命名應符合使用者的預期

**API:**當在一個新的 API 中查詢類時,使用者可能無從下手,因而依賴之前使用類似 API 的經驗,或者依賴在 API 領域通用的觀念。例如,當使用 Glide 或者 Picasso 下載並展示圖片時,使用者很可能會去查詢名為“load”或“download”的方法。

3. 為使用者提供自由的操作方式

為使用者提供撤銷操作的機會。

**UI:**某些使用者發起的操作可能含有歧義,例如“刪除”或“存檔”郵件。此時應顯示一條訊息讓使用者確認,並允許使用者撤銷此操作。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

上圖:允許使用者撤銷當前操作。圖片來源

API 應允許中斷或重置操作,並能簡單地將 API 恢復到正常狀態

**API:**例如,Retrofit 提供了一個 Call#cancel 的方法,此方法會嘗試取消飛航模式下的 call 呼叫,以及取消還未被 execute 執行的 call 呼叫,讓其之後也不再會執行。此外,如果你在使用 NotificationManager,你會發現既可以建立通知也可以取消(cancel)通知。

4. 一致性與標準

你的應用程式的使用者不應該去思考不同的文字、情景或者操作是否有著同樣的意義。

**UI:**與你的 app 進行互動的使用者在此之前已經通過與其它 app 互動得到了訓練,他們會希望各個應用的可互動元素的樣式與行為都相同。如果偏離了這些慣例,那麼使用者就會更容易出錯。

因此,UI 需要與平臺保持一致,並使用使用者熟悉的 UI 控制元件,以方便使用者快速識別並使用它們。此外,一致性應當貫穿你的整個應用。在 app 的不同介面中,使用相同的文字與圖表來表示相同的東西。例如,在你的 app 中使用者可以修改多個元素,那麼請使用相同的修改圖示。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

上圖:對話方塊應該與平臺保持一致。圖片來源

**API:**所有的 API 設計都應遵循一致性原則。

各個方法應保持命名的一致性

請參考下面的例子。假設我們有一個 interface 暴露了兩個設定不同型別 observer 的方法:

public interface MyInterface {
    
    void registerContentObserver(ContentObserver observer);
    void addDataSetObserver(DataSetObserver observer);
}
複製程式碼

使用它的使用者可能會思考:register…Observeradd…Observer 究竟有什麼區別呢?是否一個方法一次接受一個 observer,另一個方法一次可以接受多個 observer 呢?開發者要麼去認真閱讀文件,要麼去查詢 interface 的實現,來研究兩個方法的行為是否相同。

private List<ContentObserver> contentObservers;
private List<DataSetObserver> dataSetObservers;
public void registerContentObserver(ContentObserver observer) {
    contentObservers.add(observer);
}
public void addDataSetObserver(DataSetObserver observer){
    dataSetObservers.add(observer);
}
複製程式碼

因此,請為做同樣事情的方法進行 相同的命名

可以在命名時考慮使用反義詞,例如:get - set,add - remove,subscribe - unsubscribe,show - dismiss。

各個方法應保持引數順序的一致性

在過載方法時,需要確保在新舊方法中都存在的引數的順序保持一致。否則,你的 API 使用者將要花更多的時間來理解過載與被過載方法的區別。

void setNotificationUri( ContentResolver cr,
                         Uri notifyUri);
void setNotificationUri( Uri notifyUri,
                         ContentResolver cr,
                         int userHandle);
複製程式碼

避免在函式中使用連續的、同型別的引數

雖然在 Android Studio 中,使用連續的多個相同型別的引數是件簡單的事情,但是這樣做很容易導致引數順序出錯,並且很難找到這種錯誤。引數的順序應當儘可能與引數的邏輯順序一致。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

當這些引數的型別都相同時,使用者很容易犯錯。例如上圖中 county 和 country 就弄反了。

為了解決這種問題,你可以使用建造者模式,或者應用 Kotlin 的 命名引數(named parameters)

方法的引數應不大於 4 個

引數越多,意味著方法越複雜。使用者需要理解每個引數在方法中起到的作用以及與其它引數的關係,也就是說每增加一個引數都會導致方法的複雜度呈指數形式增加。當一個方法的引數超過 4 個時,就可以考慮將其中一些引數封裝在其它類中或使用構造器了。

返回值會影響方法的複雜度

當一個方法返回某個值時,開發者需要知道這個值代表著什麼,如何儲存它等。如果不需要用到這個值,那麼它也不應當對方法的複雜度造成影響。

例如,當向資料庫插入一個元素時,Room 既可以返回 Long 也可以返回 void。如使用者需要使用返回值時,首先需要了解此返回值的意義,以及如何儲存它。而在不需要返回值時,使用者可以使用 void 型別方法。

@Insert
Long insertData(Data data);
@Insert
void insertData(Data data);
複製程式碼

因此,你應當允許 API 使用者自己決定是否需要返回值。如果你正在開發一個基於程式碼生成器的庫,應該允許其生成返回多種可選型別的方法。

5. 預防錯誤的發生

建立防範於未然的設計。

**UI:**使用者經常會一心多用,因此你應當防止使用者在無意識下造成的錯誤,減少使用者“翻車”的機會。比方說你可以在毀滅性操作前彈框要求確認,或者提供正確的預設值。

比如,Google Photos 應用會彈出一個確認框來確保你刪除相簿不是誤操作;而 Inbox 的“郵件稍後提醒”功能僅需一鍵操作。

開發者也是使用者 — 第一部分:構建更具可用性的 UI 與 API 的 5 個方針

上圖:Google Photo 在毀滅性操作前彈出確認框;Inbox 在暫停收件操作時提供方便選擇的預設值。

API 應該引導使用者正確地使用 API。儘可能使用預設值。

API 應當易於使用,且能防止誤用。通過提供預設值可以幫助使用者正確使用 API。例如,當建立 Room 資料庫時,有一個預設值可以確保在升級資料庫版本時資料不丟失。由於資料庫版本對使用者來說是透明的,又因為升級時資料會保持,所以使用 Room 的應用程式對使用者來說易用性更好。

與此同時,Room 也提供了一個方法 fallbackToDestructiveMigration 用於改變這種行為,如果沒有提供遷移方法,那麼在資料庫版本改變時會銷燬並重新建立資料庫。


深入瞭解另外 5 條原則請訪問: 讓使用者認知,而不是回憶 彈性、高效的使用方式 優雅、極簡的設計 幫助使用者認識、判斷、改正錯誤 提供幫助與文件


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章