咱们对本身与之交互的全部东西的可用性都有相同的预期,包括 UI 和 API。因此,咱们用于 UI 的指导原则也能够被转化到 API。咱们在前一篇文章中已经看到了前面五条指导原则。如今,是时候看看剩下的了。html
开发者也是用户 — 第一部分 _改善 UI 和 API 可用性的五条指导原则_medium.com前端
UI: 识别出熟悉的事物所耗费的认知代价是最小的,而且它还能被上下文环境所触发。回忆意味着从记忆中取出细节,它须要多不少的时间。从一系列选项中选择,比根据记忆写出选项容易不少。一个使用常见 icon 的简单 UI 是基于识别的,一个命令行界面是基于回忆的。信息和功能应该被设计得明显,符合直觉而且容易使用。java
铅笔 icon 是一个表示编辑的符号,容易识别,与 app 无关。android
A 变量 名称应该说明它表明什么,而不是如何使用: isLoading
, animationDurationMs
.ios
A 类 名称应该是一个名词,说明它表明什么:RoomDatabase
, Field
.git
A 方法 名称应该是一个动词,说明它作什么:query()
, runInTransaction()
.github
UI: 你的应用可能被没有经验和经验丰富的用户同时使用。建立一个 UI使其迎合这两种用户的需求,并让他们习惯经常使用的操做。听说,20% 的功能被 80% 的用户使用。你须要在简洁和功能之间权衡。找出你的 app 中的那 20%,而后把它们变得尽量简单易用。使用 逐步展示原则 ,让其余用户在次要的页面使用进阶功能。算法
Wi-Fi 设置默认显示基本选项,但也包含进阶选项。它适合用户的需求。数据库
用户应当可以使用 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 时,解决这个问题的方案是使用 扩展函数。
UI: UI 应当保持简单,只包含当时和用户相关的信息。不相关或不多使用的信息应当被删除或者移到其它屏幕,由于它们的存在使用户分心,而且减小了相关信息的重要性。
Pocket Casts app 使用极简设计
这个播客 app 的集列表页面显示最少许的,和上下文相关的信息:若是用户没有下载某集,这一集的大小和下载页面是可见的;若是用户已经下载,就能够见到时长和播放按钮。同时,对于那些好奇的用户而言,详情页面包含全部这些信息,而且不止于此。
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
使用通过优化的算法,减小你须要写的代码量而且加强性能。
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 锁住较长的一段时间
。这代表查询被执行时的状态(在主线程)是不合法的。
UI: 你的用户应当可以不用文档使用你的应用。对于很是复杂或者领域专门化的 app,这也许是不可能的。因此,若是须要文档,确保它易于寻找、易于使用,并解答了常见的问题。
诸如 “帮助” 或者 “发送反馈” 之类的元素一般在导航菜单底部
API: 好的方法、类和成员命名使 API 可以阐明自身的意义。但不管 API 多好,没有好的文档就没法被使用。这就是每一个 public 的元素——方法,类,域,参数——应当用文档说明的缘由。对于你,一个 API 开发者来讲简单易见的东西,也许对于你的 API 用户来讲就不那么容易和显然了。
API: 示例代码有若干用途:他们帮助用户理解 API 的目的,用途,以及上下文。代码片断 用于解释如何使用基本的 API 功能。 教程 教用户关于 API 特定层面的知识。代码示例 是更加复杂的例子,一般是一整个应用。这三者之中,缺乏代码示例会引发最严重的问题,由于开发者看不到总体图景——你全部的方法和类是如何协做的,以及它们是如何与系统协做的。
若是你的 API 流行起来了,有可能会有数以千计的开发者使用这些例子。他们将会成为如何使用你的 API 的例子。所以,你犯的每一个错误都会让你自作自受。
这些年,咱们学习了不少关于 UI 可用性的知识;咱们知道用户们须要什么,以及他们在想什么。他们须要符合直觉、高效、正确的 UI,而且要能帮助他们用合适的方式完成特定任务。这些概念都不止于 UI,还适用于 API,由于开发者也是用户。因此,让咱们经过可用的 API 帮助他们(也是帮助咱们本身)吧。
API应当易用且不易滥用——它应该易于作简单的事,可能作复杂的事,不可能——至少难以——作错误的事 Joshua Bloch — source
感谢 Nick Butcher 和 Tao Dong.
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。