► 软件中的可用性问题,经常可以追溯到其底层概念。例如,在Dropbox中,“删除”操作会引起其他用户的困惑,而采用Unix文件夹概念则可以解释Dropbox为什么有这一缺陷。
► 软件设计在三个层次上得以实现:物理层次,包括设计按键、布局和手势,这个层次对应用户的物理和认知能力;语言层次,包括设计与用户交流的图标、提示信息和术语;概念层次,包括将底层行为设计为一系列概念。较低的两个层次,即物理层次和语言层次,主要关注用户界面中的概念表达。
► 用户拥有正确的心智模型对于软件的可用性至关重要。为了确保这一点,我们需要设计简单明了的概念,并将这些概念通过用户界面表现出来,使得这些概念易于理解和使用。
一个软件,从运行于手机上的最小程序到大型的企业系统,都是由概念组成的,每个概念都是独立的功能单元。尽管概念为一个更大的目标协同工作,但我们也可以将它们视为相互独立的个体。如果将软件视作一种化学混合物,那么概念就像是分子: 虽然相互结合在一起,但无论在哪里出现,它们的属性和行为都是相似的。
你对很多概念已经很熟悉了,并知道如何与它们进行互动。你知道如何打电话或预订餐厅,如何在社交媒体的论坛中为评论点赞,以及如何在文件夹中整理文件。一个包含常见概念且设计良好的软件会更加易于使用,只要软件设计师可以将这个概念在用户界面中忠实地呈现出来,并通过编程正确地实现这个概念。相比之下,一个概念复杂或烦琐的软件不太可能带来良好的用户体验,不管它的呈现形式多么出众或算法多么高明。
概念没有可视化的形式,它们非常抽象,这也许就是概念直到现在还没能成为人们关注的焦点的原因。我希望本书的内容可以让你相信,通过从概念的角度进行思考,并通过“看穿”用户界面背后的概念,你能够更深入地理解软件,从而更有效地使用它、更好地设计它、更精确地诊断缺陷,并在设计新的软件时更有重点,也更有信心。
我们通常不会去想正常运转的东西是如何工作的,除非它出了问题。你本以为家里的热水器可以源源不断地产生热水,直到有一天,家里有人洗澡的时间过长,轮到你洗澡时水变凉了,此时你可能才会意识到热水器是一个容量有限的储水箱。
同样,要想了解概念,我们需要看看当它们出问题时会发生什么。因此,本书的大部分内容都是失败的概念案例,这些案例发生在看似不可能的场景中,或者难以理解。在本章中,我们将看到关于概念的第一批案例,以及它们如何解释软件一些意想不到的或令人惊讶的复杂行为。
但你不要因此就排斥概念,或者认为概念的思想是模糊的、复杂的。相反,概念的思想简单明了,采用概念能够帮助你设计出比我们现在使用的大部分软件更简单、更强大的软件。
为了避免我的工作遭受磁盘损坏或意外删除的影响,我使用了一个很棒的备份软件Backblaze,它可以将文件复制到云端,并在用户需要的时候恢复文件的旧版本。它在后台持续运行,“监视”着电脑里的每个文件,如果文件发生变化,它就会即时将其复制到云端。
最近,我编辑了一段视频,我想在删除旧版本以腾出存储空间之前,确保新版本已有备份。我检查了备份的状态,它显示“你已备份:今天下午1:05”。因为我确实是在下午1:05之前编辑了这个视频,所以我认为它有了备份。但当我试着从云端恢复这个视频时,才发现那里并没有它的备份。
我联系了Backblaze的技术支持人员,他们跟我解释说,Backblaze并不是持续备份文件的,而是通过定期的扫描,汇总出新的或修改过的文件列表;当下一次进行备份时,只有该列表上的文件才会被上传到云端。因此,两次扫描之间发生的文件变化,得在下一次扫描时才会被发现。
他们告诉我,我可以单击“立即备份”按键来强制Backblaze重新进行扫描。我听从了这个建议,然后等待扫描和后续备份的完成。这时我相信新视频一定会出现在上传云端的列表中了!然而我并没有这么幸运。我已经完全糊涂了,于是再次请求帮助。原来,我的视频已经上传了,但只是上传到一个特殊的“暂存”区域,文件要每隔几小时才会从这个区域移动到恢复区域。
我的问题在于误解了Backblaze中关键的备份概念。我曾设想文件是持续上传的,并直接移动到恢复区域(见图1-1a)。但实际上,Backblaze只上传最近一次扫描生成的列表上的文件,并且在从“暂存”区域传输到恢复区域之前的一段时间里,用户仍然无法下载这些文件(见图1-1b)。
图1-1 Backblaze的运行模式
注:图a是我的假设:①我修改了一个文件;②Backblaze运行备份时,将文件复制到云端;③我从云端恢复文件。图b是实际情况:①我修改了一个文件;②Backblaze运行扫描并将该文件添加到要备份的文件列表中;③Backblaze运行备份,只将上次扫描中添加到列表的文件复制到云端;④Backblaze定期将备份文件移动到云端的恢复区域;⑤我从恢复区域恢复文件。
这只是一个小例子,但它表达了我的关键要点。我并不是想说明Backblaze的设计存在缺陷,尽管我认为它的确还可以得到改进(见第7章)。当然,如果我只按照表面的意思去理解备份,而不知道有扫描这样一件事,我可能就会丢失一些重要的文件。
我想表达的是,任何关于设计的讨论都必须围绕基本概念(在这个例子中就是备份概念),并评估概念采用的行为模式是否符合它的目的。用户界面也很重要,但在一定程度上用户界面只是服务于概念,并将概念呈现给用户。如果我们想让软件更好用,就必须从概念着手。
我朋友的笔记本电脑的存储空间快用完了。因此,她聪明地将文件按大小进行了排序,并从上到下查看列表,看看是否可以删除一些占用太多存储空间且已经不用的文件。她找出了十几份这样的文件,然后直接删除了它们。几分钟后,她接到了老板惊慌失措的电话,问她一个包含重要项目数据的大文件怎么不见了。
要知道到底是哪里出了问题,我们需要了解Dropbox的一些关键概念。Dropbox是一种流行的文件共享软件,允许多个用户查看共享的文件或文件夹,并协作更新它们。为了保持这种共享的“错觉”,Dropbox会将一个用户做出的更改同步给其他用户。那么问题是:Dropbox会在什么情况下同步什么样的更改?
艾娃(Ava)是一名派对策划人,她用Dropbox与客户进行沟通。她正在为贝拉(Bella)准备一个派对,所以她创建了一个名为“贝拉派对”(Bella Party)的文件夹,并把它共享给贝拉(见图1-2)。无论艾娃把什么文件放入文件夹,贝拉现在都可以看到。事实上,这种共享是对称的。不管贝拉放入什么文件,艾娃也能看到——无论其中一人做了什么改变,另一人都会看到同样的改变。所以,似乎只有一个文件夹存在——一个艾娃和贝拉可以协作的文件夹。
图1-2 艾娃和贝拉共享文件夹的Dropbox界面
注:艾娃与贝拉共享了名为“贝拉派对”的文件夹。图a是艾娃看到的界面,图b是贝拉看到的界面。
事实上,事情并没有那么简单,因为其中一人并不能看到另一人做的所有更改。也许贝拉不希望这个文件夹被命名为“贝拉派对”,所以她给这个文件夹起了一个新的名字——“我的派对”(My Party)。问题是,艾娃现在看到的文件夹的名字变了吗?
这里有两种可能:贝拉的操作会改变艾娃看到的文件夹名称,在这种情况下,同一个文件夹只有一个名称;或者,同一个文件夹有两个名称,艾娃使用一个,贝拉使用一个。
那么到底是哪种情况呢?其实两种情况都有可能发生,这取决于文件夹的共享方式。在这个例子中,艾娃确实与贝拉共享了文件夹,但贝拉的更改只有自己能看到,而艾娃看不到这个更改。但是假设艾娃在“贝拉派对”中创建了另一个名为“贝拉计划”(Bella Plan)的文件夹(见图1-3a)。由于它的父文件夹是共享的,所以“贝拉计划”也是隐式共享的。现在,如果贝拉把“贝拉计划”改名为“我的计划”,那么艾娃将会看到这个更改。
你可能会认为这种结果的差异是人们在Dropbox开发过程中随意选择的结果,或者你可能会认为这是一个漏洞。事实上,这两种说法都不对。这种明显古怪的结果是由Dropbox的基础设计直接导致的。
在解释具体原因之前,我们再来考虑一个问题。如果贝拉删除一个文件夹会发生什么?艾娃那里的副本也会被删除吗?同样,这取决于具体情况。如果贝拉删除了“贝拉派对”,只有她自己的那个文件夹会消失,但如果她删除的是“贝拉计划”,艾娃的文件夹也会被删除。Dropbox确实在这两种情况下给出了不同的提示信息,其中一个提示信息更全面(见图1-3b)。但奇怪的是,这一更全面的解释是在第一种情况下给出的,而不是第二种情况,可是第二种情况中的删除会导致文件永久丢失。
图1-3 Dropbox删除文件夹时的提示信息
注:“贝拉派对”文件夹已共享(图a)。如果删除该文件夹,提示信息会通知你,删除将不会影响其他用户(图b)。如果删除其中包含的文件夹“贝拉计划”,则会出现一条不同的提示信息,令人惊讶的是,它没有警告你其他用户也将丢失该文件夹(图c)。
现在我们可以解释我朋友的经历了。她的老板本想与她共享一个文件,却共享了整个文件夹。当我的朋友删除她不需要的文件时,她是从共享文件夹中删除该文件的。这样一来,所有人的文件都被删除了,包括她老板的文件。
要想知道在不同的共享场景中会发生什么,最好先弄清楚我们的期望是什么。每个物体都有一个名称,比如猫项圈或汽车牌照,软件设计也应该有一些与物体名称一样简单而熟悉的标签,这种标签就是“元数据名称”。元数据名称是更一般意义上的元数据概念的一个实例。在元数据概念中,我们可以将用来描述对象的数据,如照片的标题,附加到对象上。
关于删除,最简单的设计是在删除文件或文件夹时使文件或文件夹消失。我们可以使用一个技术术语“嗖删除”(deletion as poof)来命名这种删除方法。当你单击删除键时,“嗖”的一下,文件就不见了。这里的隐含概念是,软件有一个文件存储池,用户可以对池中的文件进行添加和删除操作。由于删除概念非常基础和普遍,因此人们没有专门为它命名。在文件共享软件的设计中,我们希望有一个单独的共享概念,但是这个共享概念可以允许不共享的操作,这样你就可以删除别人与你共享的文件或文件夹,释放你账户的存储空间,同时不删除其他人的副本。
但是至少对Dropbox来说,文件或文件夹的名称不是元数据,删除操作也不是只从文件存储池中删除文件或文件夹。我们理解的删除概念和共享概念本身是没问题的,只不过它们不是Dropbox使用的概念。如果你使用了错误的概念模型,短时间内可能不会出问题。正如我们已经看到的,在某些场景下,这些概念有效,但在另一些场景下,却可能造成失败,并带来严重的后果。
Dropbox实际使用的概念是非常不同的(见图1-4b)。当Dropbox的一个文件位于文件夹中时,该文件的名称不属于该文件本身,而是属于它的父文件夹。可以将Dropbox的文件夹看作一组标签的集合,每个标签都包含一个文件的名称,以及指向该文件的链接。Dropbox的文件夹概念被称为Unix文件夹。从名字上就可以看出,这并不是Dropbox发明的,而是从Unix借用来的。
图1-4 Dropbox文件夹的两种可能概念
注:在元数据概念中,名称是文件夹的标签(图a)。在Unix文件夹概念中,名称是父文件夹中的条目(图b)。
如图1-4b所示,艾娃和贝拉每个人都有自己的Dropbox根文件夹,并且她们各自的这两个文件夹对于独立且被共享的“贝拉派对”文件夹都有各自的条目入口。贝拉重命名“贝拉派对”将会改变她自己Dropbox文件夹中的条目,而艾娃文件夹中的条目没有改变。
相反,二级共享文件夹“贝拉计划”只有一个条目,它属于独立且被共享的“贝拉派对”这个父文件夹。因为这个文件夹只有一个条目,所以艾娃和贝拉看到的是同一个条目。当贝拉重命名该文件夹时,她更改的是共享文件夹中的这个条目,所以艾娃也会看到这个更改。
我们现在可以用Unix文件夹概念来解释Dropbox中的删除操作了。删除操作并不会删除文件夹,只会删除它的条目。因此,如果贝拉删除了“贝拉派对”文件夹,她只是从自己的文件夹中删除了该条目,而艾娃看到的内容不会改变。但是,如果贝拉删除了“贝拉计划”文件夹,她就会从共享文件夹中删除该条目,艾娃也看不到“贝拉计划”了。
你可能会认为Dropbox的缺陷是显而易见的。我对Dropbox的缺陷一点儿也不惊讶。Dropbox本身没有什么问题,只要理解它就可以使用它。但我敢肯定理解它的人只占少数。我们向麻省理工学院计算机科学专业的学生展示了以上两种情况,发现他们中的许多人,甚至是那些经常使用Dropbox的人,都感到困惑。
即使你理解了所有这些微妙之处,我想说这里仍然有一个问题。以上两种情况的区别是:操作主体的文件夹是共享的文件夹,还是包含在另一个本身就被共享的文件夹中。但这一区别在用户界面中不容易识别,所以必须先弄清楚遇到的是哪种情况,这是一件非常麻烦的事。
此外,我看不出用这种武断的区分来决定操作的合理性。为什么我只能给根文件夹命名?为什么我不能给所有与我共享的文件夹命名?或者反过来说,如果重命名文件夹是我们共享工作的一部分,为什么我只能重命名某些文件夹?
假设这些确实是Dropbox存在缺陷的证据,那我们可以问:这是什么样的缺陷?这种缺陷肯定不是程序错误,因为Dropbox多年来一直如此。我们可能会想,这算不算用户界面的缺陷,不过这似乎也不太合理。当然,当你做的更改影响到其他用户时,Dropbox应该给出更多的提示信息。但这也可能徒增复杂性,而且经验表明,如果提示信息出现得太频繁,用户就会忽略它们。
真正的问题在于更深的层次,在于给文件和文件夹命名的本质,以及这些命名是如何与文件夹及其文件相关联的。这就是我说的概念设计问题。所以Dropbox的缺陷在于开发人员心中已经有了一些确定的概念,并正确地实现了这些概念,但这些概念却与大多数用户心中的概念不一致。更糟糕的是,这些概念与用户的需求并不匹配。
为了更好地理解概念设计,将软件设计分为多个层次可能会有所帮助(见图1-5)。虽然这是我自己的分类,但与前人提出的一些分类类似。
图1-5 设计的层次
设计的第一个层次是物理层次,这个层次是关于组件的物理特性的。即使软件的界面仅仅在一块触摸屏上运行,也会有物理特性,只不过可能比较有限。在这个层次上,设计师必须考虑人类身体的能力。设计师需要考虑软件如何与视障或聋哑用户进行交互,这就是易用性的问题。
人类的一些共同生理特征决定了某些设计原则。比如,我们有限的视觉采样率导致了感知融合,这使我们很难区分发生在30毫秒以内的事件,所以30帧/秒的画面就足以让电影看起来很流畅。这同时也告诉我们,如果系统反应时间超过30毫秒,用户就会觉得系统延迟,所以应当避免给出进度条,如果时间过长,应该给用户中止软件运行的机会。同样,菲茨定律(Fitt's Law)预测了用户将光标移动到目标点需要的时间,并解释了为什么菜单栏应该位于屏幕顶部,就像macOS的桌面那样,而不是像Windows系统桌面那样位于软件的窗口内部(见图1-6)。
图1-6 哪个菜单的位置更方便用户访问
注:图a是macOS的菜单位置,软件的菜单栏总是出现在桌面的顶部;图b是Windows系统的菜单位置,菜单栏是软件窗口的一部分。
设计的第二个层次是语言层次。这个层次关注的是为了表达软件的运行方式而使用的语言,以帮助用户浏览软件、了解可用的操作以及操作将产生的影响、软件已经发生的行为等。在物理层次进行设计时,必须尊重用户身体特点的多样性;而在语言层次进行设计时,必须尊重用户在文化和语言上的差异。
显然,软件中的按键名称和消息提示,都应该根据用户是英国人还是意大利人而有所不同。我至今还记得小时候在意大利度假时,怎么也记不住标有calda的水龙头出的不是冷水。设计师还必须意识到文化差异。在欧洲,红色圆圈的路标表示任何车辆都不允许通行;而大多数美国司机却可能觉得禁行标识应该是红色的斜杠。
一般来说,当用户界面的设计师谈论对一致性的需求时,他们通常指的就是语言层次上的语言使用。一致性包括确保在整个用户界面中,对相同的词语采用了相同的使用方式。例如,文件容器不应该在一个系统中既被称为“文件夹”,又被称为“目录”,并且图标的使用要有系统性的考虑。图1-7展示了谷歌的图标设计如何违反了一致性原则。谷歌为两个不同的功能设计了几乎相同的图标(几年后谷歌解决了这个问题)。这两个图标都用了一组黑色方块,但其中一个对应的功能是打开谷歌的软件,另一个对应的功能则是切换到网格视图。
图1-7 谷歌在图标使用上的不一致性
注:图a是打开谷歌的软件和切换到网格视图的原始图标;图b是修改后对应的新图标。
设计的第三个也是最高的层次是概念层次。它关注设计背后的行为,即关注由用户和软件本身执行的操作,以及这些操作对底层结构的影响。与语言层次相比,概念层次与交流或文化无关,尽管我们将在第9章中看到,关于概念的先验知识将使我们更容易了解和使用新的概念。
在编程中,抽象(abstraction)和表达(representation)有着重要的区别。抽象是抓住编程思想的本质,也可能用于对观测到的行为进行说明。而表达是通过代码实现这个本质。
同样,用户交互既有抽象,也有表达。抽象是概念,是软件结构和行为的本质,也是概念层次的设计主题。表达是概念在用户界面中的体现,包括所有的物理和语言细节,是较低层次的设计主题。
就像同一个编程的抽象可以有不同的表达一样,一个概念也可以在不同的用户界面中得到实现。在编程中,程序员首先会考虑抽象,然后才考虑表达。软件设计师也同样先考虑概念层次,然后才考虑较低层次。到目前为止,设计师还没有办法不依靠具体的用户界面来表达概念设计的思想。本书的目标就是要表明,这些思想可以得到直接的表达,而且可以先于和独立于表达方式。
在大多数软件中,用户遇到使用困难通常不是因为软件的功能太少或太多。常见的情况是,用户不能有效地使用软件实际的功能。这可能是由于用户不会主动去寻找功能,也没有预先想到会有哪些功能。
然而更常见的情况是,用户知道软件中有这些功能,却仍然无法正确地使用它们。最常见的原因是,用户的心智模型不正确,或者说与软件设计师和程序员的心智模型不一致。研究一再表明,用户对他们使用的设备往往有着模糊、不完整甚至是不一致的心智模型,这并不令人意外。但他们确实能够形成设计师设想的概念,即使不是在每个细节上都一致,但至少在形式上一致。
但是,当用户的心智模型与开发人员的心智模型不一致时,他们就无法有效地使用软件中的功能,正如我们在Dropbox例子中看到的那样。用户可能会因此遭受严重的损失,或者因为害怕某些错误会带来高昂的代价,而只使用其中的一小部分功能。
解决这个问题的一个糟糕办法是培训用户。这个办法通常不会起作用,因为大多数用户都会拒绝花时间学习如何使用软件,他们认为熟能生巧。所以一个更好的解决办法是设计软件的概念,使软件简单、灵活并能很好地适应用户的需要;同时通过用户界面向用户传达这些概念。
概念本身既是用户想要的心智模型,也是软件的规格。 用户界面设计师的任务就是设计出类似设计大师唐纳德·诺曼所说的“系统形象”。用户界面能够准确地对应概念模型,这样用户就能够获得与软件概念一致的心智模型。
图1-8描述了这一点。图1-8b是用户的心智模型,图1-8c是用户界面,图1-8d是程序员编写的代码。为了确保软件成功,我们需要了解用户(可以通过调查用户需求、工作环境以及心理素质实现),确保代码的设计符合规范(可以通过测试、审查和验证实现),并精心设计一个可用的用户界面。
图1-8 概念与心智模型
注:概念(图a)的核心作用,在于能够使用户的心智模型(图b)和开发人员的心智模型(图d)保持一致。通过仔细地将概念映射到用户界面(图c),这些概念不仅得到了完全的表达,而且还隐含地传递给了用户。
但最重要的是,要使用户头脑中的心智模型与开发人员头脑中的心智模型保持一致,需要用户和开发人员共享相同的概念,也需要在用户界面中准确地表达这些概念。
► 找一个你用得不太好的软件,问问自己其中涉及哪些概念,并对照检查你对软件运行方式的假设是否与实际相符。如果不符,你是否能找到解释软件运行方式的更准确的概念?
► 作为一款软件的设计者,考虑一下用户觉得最难用或最容易误用的功能。你能指出一个或多个可以为这些功能负责的概念吗?
► 要清楚自己设计的层次。从概念层次开始设计,然后依次往下进行。在较低层次勾画概念可以帮助你更直观地把握它们,但在对概念有清晰的认识之前,一定要拒绝优化用户界面的诱惑,例如,优化字体、颜色和布局等细节。
► 当你听到用户对于一款软件在物理或语言层次的抱怨时,想想它潜在的问题是否存在于概念层次。