购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

03 概念的结构,从样式概念到预订概念

本章预览

► 概念的定义包括名称、目的、状态、操作和操作原则。操作原则用于展示如何通过操作实现目的,这是理解概念的关键。

► 每个概念都是某人在某个时间出于某种目的而发明的。随着时间的推移,大多数被广泛使用的概念都得到了进一步的扩展和完善。

► 大多数概念是通用的,可以应用于不同类型的数据以及场景中。通用性有助于概念的重用,也有助于提炼概念的本质。

► 概念可以被相互独立地设计和理解。为了简化软件设计,可以将设计分解成不同的子问题,许多子问题都可以通过概念的重用来解决。

到目前为止,我一直在用相对模糊和笼统的术语讨论概念。但究竟什么是概念呢?为了更有效地使用概念,我们需要超越大众的一般性讨论,开始关注细节。在本章中,我将向你展现如何定义概念。这种定义将阐明什么是概念,什么不是概念,而且将为设计概念提供指南。

我将用三个概念作为例子,重点关注它们的结构,同时也会谈到概念的产生以及使用,并指出概念设计上的一些精妙之处。

当然,概念并不能解决所有的设计问题,但是确实可以通过找出特定的概念来帮助我们发现设计中的挑战。概念不仅包含它表示的行为、关于其设计的所有现存知识、可能出现的实现问题,还包括软件设计师处理这些问题的各种方法。

废纸篓,苹果公司的杀手级概念

废纸篓概念是苹果公司在1982年为丽萨电脑发明的。往废纸篓图标里面扔东西时,图标会有可爱的动态凸起,清空它时还会发出俏皮的嘎吱声,这些都是操作系统更友好的象征(见图3-1)。从那时起,废纸篓概念变得无处不在,不仅出现在其他操作系统的文件管理器中,还出现在许多软件中。

图3-1 1984年的麦金塔电脑桌面,右下角就是废纸篓(Trash)

乍一看,废纸篓图标是用于删除文件和文件夹的,只不过不用执行传统的删除命令,用户只需要将要删除的东西拖进废纸篓。然而,真正的创新并不是用户可以把东西拖进废纸篓,而是用户还可以恢复它们。用户打开废纸篓,可以查看里面的项目,然后,可以通过将某个项目拖到电脑的其他位置来恢复它。从这个意义上来说,废纸篓概念的目的并不是删除,而是撤销删除。

当然,用户也必须能够永久删除文件,以便为新文件腾出存储空间。这可以通过清空废纸篓来实现。总结一下,当用户想删除一个项目时,将它拖进废纸篓;当用户想恢复它时,将它从废纸篓里拖出来;当用户因存储空间不足想永久删除项目时,可以清空废纸篓。

为了使概念设计更实用,我们还需要一种简洁准确地定义概念的方法。图3-2显示了如何定义废纸篓概念,这一定义与我刚刚对废纸篓概念的解释完全一致。

图3-2 废纸篓概念的定义

首先给出概念的名称,然后在随后的方括号中给出类型列表,类型具体是什么要根据概念来定。在这里只有一种类型即项目(Item)。在一个概念中,项目可以是系统里的文件;在另一个概念中,项目可以是电子邮件客户端的邮件。

其次是对概念目的(purpose)的介绍。然后介绍概念状态(state),将概念中涉及的项目组织成各种结构。在废纸篓概念中,只有两种状态:可访问(accessible),表示仍在废纸篓以外、可以访问的项目集合;已删除(trashed),表示已删除但尚未永久删除的项目集合。

在状态之后是概念操作(actions),用以描述概念的动态行为。操作是即时的,即不涉及时间长度,但操作之间可以间隔任意时间。对操作的描述表明当操作发生时状态将如何变化。例如,删除一个文件,就是将这个文件从可访问文件夹移动到已删除文件夹。对概念操作的描述可能还包括一些限制操作发生的前提条件,比如只能删除可访问但未被删除的文件。除图3-2中伪代码给出的操作描述之外,完整的操作描述还应包括文件的创建,因为被删除的文件肯定已经通过某种方式完成了创建。

最后介绍的是操作原则(operational principle),展示如何通过操作的组合实现概念的目的,包含一个或多个典型的使用场景。在废纸篓概念中有两种场景。一种是恢复场景:删除一个文件后再恢复它。另一种是永久删除场景:删除一个文件后,再清空废纸篓,用户将再也无法访问这个文件。

从狭义的技术意义上来讲,操作原则并没有增加任何信息,因为你完全可以从操作规范中推理出任何使用场景。但是为了帮助我们理解一个概念设计,以及概念的预期用途,操作原则就是必要的。

通过对操作的精确描述,以及对操作和操作原则的严谨定义,概念就可以变得更加清晰。因为大多数读者并不关心概念描述的细节,所以我将在附录部分对细节进行介绍。

废纸篓的设计缺陷

废纸篓概念非常成功,并得到了广泛使用。它出现在所有文件管理器(Mac、Windows和Linux)、电子邮件客户端(例如苹果邮件和Gmail)以及云存储系统(例如Dropbox和Google Drive)中。但这个概念并非都是完全相同的操作,一种常见的变体就是,当删除某个文件一段时间后,例如30天,系统就会自动永久删除这个文件。

在麦金塔电脑中,整个系统只有一个废纸篓,这会带来一些不好的后果。首先,当你插入和移除外部驱动器时,如果从这些驱动器中删除文件,废纸篓的内容就会随之变化。这有时会让人感到不安,比如你可能在废纸篓中看到一个文件并打算恢复它,但随后发现它已经消失了,因为外部驱动器被移除了。

下面场景中的问题更加突出。假设你插入了一个U盘并尝试将文件复制到里面,却发现U盘没有足够的存储空间,因此你决定删除U盘上的一些文件。然后当你再次尝试将文件复制到U盘里时,却依然失败了。你意识到,只是删除文件并不能腾出存储空间,要想腾出存储空间,你还必须清空废纸篓。

现在你面临一个困境。如果不清空废纸篓,你将无法将新文件复制到U盘。但是,如果清空废纸篓,之前从其他存储设备上删除的文件也将丢失,并且无法恢复。

令人惊讶的是,这个问题竟然被搁置了30多年,直到2015年苹果公司发布操作系统OS X El Capitan才得以解决。这个解决方案更像一种变通办法,只是增加了一个“立即删除”选项,允许用户一键永久删除废纸篓中指定的文件。

废纸篓的另一个设计缺陷与已删除文件的显示方式有关。几十年来,用户一直没有办法按删除日期对废纸篓中的文件进行排序。如果你不小心删除了一个文件,然后希望通过废纸篓恢复它,就可能会遇到麻烦。因为如果你还没有清空过废纸篓的话,里面可能会有数千个文件。如果你也没记清已删除文件的名字,那就真的没办法找到它了。

2011年,苹果公司的OS X Lion操作系统开始允许用户按“创建日期”对文件夹中的文件进行排序,而这个日期对于废纸篓而言就应该是文件删除日期。在第5章中,我会更详细地解释这个设计,并展示它如何将概念更巧妙地融合在一起。

样式,桌面出版背后的概念

第二个例子关于样式概念。图2-2和图3-3分别介绍了Adobe InDesign、微软Word以及苹果Pages。这些软件的目的是帮助用户更容易实现格式的一致化。

图3-3 微软Word(图a)和苹果Pages(图b)中的样式(Style)概念

使用这些软件时,你需要为文档中的段落指定样式。例如,你可以将每个段落的标题都设置为统一的样式。如果你想让所有的标题字体都加粗,你只需要修改标题样式的格式,将它设置为粗体,就可以同步更新所有的段落标题了。

下面是样式概念的操作原则。该操作原则实际上是一个相当复杂的场景,包括创建多个段落、为多个段落指定统一的样式以及修改该样式。操作原则并不总是最简单的场景,但起码能展示概念如何使用。而且,操作原则要想展示如何让段落格式保持一致,需要不止一个段落。在样式概念的定义中,操作原则是这样描述的:定义一个样式s的格式为f,将f指定给元素e1和e2,然后重新定义s的格式为f',那么e1和e2都将具有新的格式f'。

为了使样式概念起作用,它的状态就需要很复杂(见图3-4)。样式概念的状态有三种映射关系:一种是指定(assigned),为元素指定一种样式;另一种是定义(defined),为样式定义一种格式。在样式概念中,格式是抽象的,你可以将它看作所有格式属性的集合,如粗体、12磅、Times Roman等。第三种是格式化(format),就是将上述两种映射组合起来,用于简要记录元素的格式。因此指定样式s给元素e,且用格式f定义样式s,那么元素e就拥有了格式f。

图3-4 样式概念的定义

我定义了样式概念的两个操作:一个为元素指定样式,另一个为样式定义格式。第二个操作既可用于创建一个样式的格式,也可用于为样式更新一个格式。这两个操作也可以分别进行,不管怎样都是有效的。

似是而非的样式概念

样式概念得到了广泛的使用。微软Word、苹果Pages等文字处理软件以及Adobe InDesign和QuarkXPress等桌面出版软件中都使用它,不仅可以用它来设置段落样式,还可以用它来设置字符样式。在微软的PowerPoint中(见图3-5a),样式概念允许用户设置“颜色主题”(Theme Colors),颜色主题包含一组预定义的样式,这些样式可用于幻灯片中的各种文本(Text),例如标题、超链接、正文,以及背景(Background)。网页中的串联样式表(cascading style sheets,CSS)也属于样式,它将网页的格式与内容清晰地分离开来。

图3-5 微软PowerPoint中的颜色主题(图a)和Adobe系列软件中的色板(图b)

有时,软件对样式概念的使用并不是很明显。如在Adobe InDesign和Adobe Illustrator中,你可以通过色板(Swatches)为元素着色(见图3-5b)。一开始你可能没有注意到色板是可以修改的。如果你用红色为多个元素着色,那么不用对这些元素都变成红色感到奇怪。但是现在,如果你打开色板并选择了绿色,你会看到刚才所有这些红色元素都变成了绿色。这个功能非常有用,因为它可以让用户轻易保持颜色的一致性,而不用每次都在色板中设置颜色。

有些例子看似是某个概念,事实上却不是这个概念。苹果公司的色板(见图3-6a)几乎出现在该公司的所有软件中,允许用户进行颜色的选择。苹果公司的色板看起来与Adobe的色板非常相似,因此你会认为苹果公司的色板可能也是样式概念的一个实例。但是在使用了苹果公司软件后你会发现,虽然可以删除色板或添加新色板,但无法改变已有色板的颜色。可是这种对样式格式的修改能力,对于样式概念来说是必不可少的。没有了这个功能,样式概念根本无法工作,也就是说它的操作原则失败了。如果添加新样式不能影响与旧样式有关的元素,那么一旦元素的格式被重新定义,就无法再统一更改元素的样式。

图3-6 苹果公司的色板(图a)和苹果公司的TextEdit(图b)
注:这两个案例看似是样式概念的实例,实际却不是。

另一个类似的问题出现在苹果公司最基本的文字处理软件TextEdit的样式(见图3-6b)中。TextEdit的名字已经暗示了样式概念,而且用户确实可以创建和删除所谓的样式,还可以修改它们。但是,当将样式应用于段落时,它只能更新当前段落的格式,之前段落的格式仍然保持不变。样式与段落之间没有关联。因此,更改样式只影响以后的段落格式,而不会影响之前的段落格式。

样式概念还在不断丰富,甚至涉及一些格式的分层。例如,部分样式允许仅设置某部分格式属性,比如将文本设为斜体但不影响字号大小;样式继承(style inheritance),将一种样式定义为另一种样式的扩展;覆盖,即元素的格式由具有某种覆盖格式的样式来定义。

预订,一个19世纪的概念

在本章的最后一个例子中,我们来讨论一个早在软件出现之前就已存在的熟悉概念——预订概念(reservation)。预订概念有助于有限资源的有效利用。资源提供者希望资源利用率尽可能高;消费者希望有需要时就可以得到并使用资源。

预订概念是这样工作的(见图3-7)。想要使用资源的消费者尝试预订资源,如果该资源尚未被预订,则预订成功;然后消费者使用该资源。

图3-7 预订概念的定义

预订概念要起作用,就需要跟踪与预订相关的内容,包括被预订的资源和预订资源的消费者。消费者除进行预订并最终使用资源之外,还可以在他们决定不需要资源的时候取消预订。

你可能预订过餐厅、图书馆书籍,以及音乐会座位,这些都不是新鲜事。但值得注意的是这里对预订概念采用的解释形式。预订概念的目的是有效利用资源。预订概念的操作原则是关于如何预订并使用资源。预订概念的状态是与预订相关的全部内容。最后是预订概念的操作:预订、使用资源和取消预订。

在预订概念的描述中,有一个集合来表示哪些资源可用,以及一个从用户到可预订资源的映射。这种映射与样式概念定义中的映射不同,它是一对多的,即一个用户可以预订多个资源。

预订概念中的操作包括由资源所有者(如餐厅)执行的用于提供和回收资源的行为。如果资源已被预订,则回收资源会有点麻烦。为简单起见,预订概念的定义规定,资源在被预订的情况下不能回收,但实际上更好的设计是允许回收,比如隐式地取消预订。在预订概念定义的最后,操作原则给出一个警告:在没有取消预订的情况下,才能正常使用资源。

设计师的预订

和任何其他概念一样,预订概念也有很多变体和附加功能。通常,资源的可用性与时间相关。在餐厅预订系统中,消费者只需要选择开始用餐的时间,结束时间是由餐厅老板决定的。但这是一个棘手的问题,因为老板如果设置太长的用餐时间,那么可服务的客人数量就会减少,但如果用餐时间设置得太短,预订的客人就需要等待。资源可能与特定的物理对象相关,例如飞机上的座位、餐厅中的任何一张桌子,或某本书的任何副本。

由于预订通常是免费的,资源提供者还需要防止用户总是预订资源却从不真正使用它。餐厅预订系统通过餐厅老板记录的客人缺席次数来实现这个目的。如果客人有太多次缺席,他的账户将被停用。预订系统还需要防止消费者的预订发生冲突,例如在同一晚预订两家不同的餐厅。航空公司有复杂的规则来检测预订冲突。

预订概念在很多不同的领域都非常有用。铁路运输要求列车在进入路段之前预订轨道来保证安全,这样系统就可以确保不会有两列火车同时占用同一路段。在网络中,有一种资源预留协议(resource reservation protocol,RSVP),它允许路由器预订带宽,以便在某段时间内保证一定水平的网络性能,即“服务质量”。

练习与实践

► 要设计或分析一个软件,首先要确定其中的概念。为每个概念取一个好名字,并对概念目的做精辟的总结和概括,同时为每个概念制定一个操作原则。要钻研得更深,还需列出概念的操作,并找出支持操作的状态。

► 如果一个概念缺乏独特的行为,你就无法为它提出一个典型的操作原则,甚至不能列出它的操作,那它可能根本就不是一个概念,你可能需要扩展它直到它成为一个真正的概念。

► 找一个系统的数据库模式或类结构,将其表示为实体关系图,然后将图分解为更小的图(可以重叠实体但不要重叠关系),使每个图都呈现一些系统的功能。这些较小的图就是不同概念的状态。

► 不要将数据模型作为一个整体设计,要为每个概念独立开发“微模型”,然后将它们合并到公共实体上,以形成全局模型。

► 下面是一个有趣且有益的练习。找一个有趣的概念并研究其历史。它可能是一个独立于软件存在的概念(如预订),也可能是你最喜欢的软件中的一个概念。它在什么时候产生,是由谁发明的?它随着时间推移发生了哪些变化? 8fbWVfmE0d68Vbxl3C3/EYh+l7+fC1bZWz4jZ9ylHrVffq6ey1OFOyjoTrGyql7b

点击中间区域
呼出菜单
上一章
目录
下一章
×