第14章 其他质量属性
质量不是当你所做的符合你的意图时所发生的情况。质量是当你所做的符合客户期望时所发生的情况。
——瓜斯帕里(Guaspari)
第 4 章——第 13 章 分别讨论了对软件系统很重要的一个特定质量属性(QA)。那些章节中的每一章都讨论了其特定质量属性是如何定义的,给出了关于该质量属性的通用场景,并展示了如何编写具体场景以表达关于该质量属性的精确含义层次。此外,每一章都提供了一组在架构中实现该质量属性的技术。简而言之,每一章都呈现了一种用于指定和设计以实现特定质量属性的组合(方法)。
然而,你无疑可以推断出,那十章内容仅仅是触及了你在开发的软件系统中可能需要的各种质量属性的皮毛。
本章将展示如何针对我们“A 清单”中未涵盖的质量属性构建同样的规范和设计方法。
14.1 其他种类的质量属性
本书 第二部分 到目前为止所涵盖的质量属性都有一些共同点:它们要么涉及正在运行的系统,要么涉及创建和部署系统的开发项目。换句话说,要测量这些质量属性之一,要么在系统运行时测量它(可用性、能效性、性能、安全性、可靠性、易用性),要么在系统不运行时测量对系统进行某些操作的人员(可修改性、可部署性、可集成性、可测试性)。虽然这些质量属性无疑为你提供了一份重要质量属性的“A 清单”,但还有其他可能同样有用的质量属性。
架构的质量属性
另一类质量属性侧重于衡量架构本身。以下是三个例子:
-
可构建性:这个质量属性衡量架构本身对于快速高效开发的适宜程度。它通过将架构转化为满足其所有需求的工作产品所需的成本(通常以金钱或时间衡量)来度量。从这个意义上说,它类似于衡量开发项目的其他质量属性,但不同之处在于测量所针对的知识与架构本身有关。
-
概念完整性:概念完整性是指架构设计的一致性,它有助于架构的可理解性,并在其实现和维护中减少混乱并增加可预测性。概念完整性要求在整个架构中以相同的方式做相同的事情。在具有概念完整性的架构中,少即是多。例如,组件之间有无数种相互发送信息的方式:消息、数据结构、事件信号等等。具有概念完整性的架构将采用少量的方式,并且只有在有充分理由的情况下才提供替代方案。类似地,组件都应该以相同的方式报告和处理错误,以相同的方式记录事件或事务,以相同的方式与用户交互,以相同的方式清理数据等等。
-
市场适销性:架构的“市场适销性”是另一个值得关注的质量属性。有些系统因其架构而闻名,这些架构有时具有其自身的意义,独立于它们为系统带来的其他质量属性。当前对构建基于云的和基于微服务的系统的强调告诉我们,对架构的认知至少与架构所带来的实际质量属性一样重要。例如,许多组织感到有必要构建基于云的系统(或其他一些“当下流行的技术”),无论这是否是正确的技术选择。
开发可分发性
开发可分发性是设计软件以支持分布式软件开发的质量属性。与可修改性一样,这种质量是根据开发项目的活动来衡量的。如今许多系统都是由全球分布式团队开发的。采用这种方法时必须克服的一个问题是协调团队的活动。系统的设计应使团队之间的协调最小化,也就是说,主要子系统应表现出低耦合性。无论是对于代码还是对于数据模型,都需要实现这种最小化的协调。开发相互通信的模块的团队可能需要协商这些模块的接口。当一个模块被许多其他模块使用,且每个模块由不同的团队开发时,沟通和协商就会变得更加复杂和繁重。因此,项目的架构结构和社会(及商业)结构需要合理地协调一致。对于数据模型也有类似的考虑。开发可分发性的场景将涉及正在开发的系统的通信结构和数据模型的兼容性,以及进行开发的组织所采用的协调机制。
系统质量属性
诸如飞机、汽车和厨房电器等依赖于嵌入式软件的物理系统,其设计要满足一系列质量属性要求:重量、尺寸、耗电量、功率输出、污染排放、耐候性、电池寿命等等。软件架构往往会对系统的质量属性产生深远影响。例如,不能高效利用计算资源的软件可能需要额外的内存、更快的处理器、更大的电池,甚至可能需要额外的处理器(我们在 第 6 章 中讨论了能效性作为质量属性的话题)。当然,额外的处理器会增加系统的耗电量,同时也会增加其重量、物理外形尺寸以及成本。
相反,一个系统的架构或实现能够使软件满足其质量属性要求,也可能阻止软件满足其质量属性要求。例如:
- 一款软件的性能从根本上受到运行它的处理器性能的限制。无论你把软件设计得多么好,你都无法在爷爷的古董笔记本电脑上运行最新的全球天气预报模型并期望知道明天是否会下雨。
- 在防止欺诈和盗窃方面,物理安全可能比软件安全更重要且更有效。如果你不相信这一点,那就把你笔记本电脑的密码写在一张纸条上,把它贴在你的笔记本电脑上,然后把它留在一辆车窗未关的未上锁的汽车里。(实际上,请不要这样做。把这当作一个思想实验。)
这里的教训是,如果你是驻留在物理系统中的软件的架构师,你将需要了解对整个系统实现而言重要的质量属性,并与系统架构师和工程师合作,以确保你的软件架构对实现这些质量属性有积极贡献。
我们为软件质量属性引入的场景技术同样适用于系统质量属性。如果系统工程师和架构师尚未使用这些技术,请尝试引入它们。
14.2 使用质量属性标准列表——或者不使用
架构师手头不乏软件系统的质量属性列表。标题为“ISO/IEC FCD 25010:系统与软件工程:系统与软件产品质量要求与评估(SQuaRE):系统与软件质量模型”的标准就是一个很好的例子(图 14.1)。该标准将质量属性分为支持“使用质量”模型的那些和支持“产品质量”模型的那些。这种划分在某些地方有点牵强,但它仍然开启了对一系列令人惊叹的质量属性进行分而治之的探索。
ISO 25010 列出了以下涉及产品质量的质量属性:
- 功能适用性:产品或系统在规定条件下使用时,提供满足明示和隐含需求的功能的程度。
- 性能效率:在规定条件下相对于所使用资源量的性能。
- 兼容性:产品、系统或组件在共享相同硬件或软件环境时,与其他产品、系统或组件交换信息和/或执行其所需功能的程度。
- 易用性:产品或系统在特定使用环境下,能被特定用户有效地、高效地和满意地用于实现特定目标的程度。
- 可靠性:系统、产品或组件在规定条件下、规定时间内执行规定功能的程度。
- 安全性:产品或系统保护信息和数据,以使人员或其他产品或系统具有与其授权类型和级别相适应的数据访问程度。
- 可维护性:产品或系统能够被预期的维护人员进行修改的有效性和效率程度。
- 可移植性:系统、产品或组件能够从一个硬件、软件或其他操作或使用环境转移到另一个环境的有效性和效率程度。
在 ISO 25010 中,这些“质量特性”各自由“质量子特性”组成(例如,不可抵赖性是安全性的一个子特性)。该标准以这种方式艰难地完成了对近六十种不同质量子特性的描述。它为我们定义了“愉悦”和“舒适”的质量。它区分了“功能正确性”和“功能完备性”,然后又恰当地添加了“功能适当性”。要表现出“兼容性”,系统必须具有“互操作性”或者仅仅是“共存性”。“易用性”是产品质量,而不是使用质量,尽管它包括“满意度”,而“满意度”是使用质量。“可修改性”和“可测试性”都是“可维护性”的一部分。“模块化”也是如此,它是实现质量的一种策略,而不是其自身的目标。“可用性”是“可靠性”的一部分。“互操作性”是“兼容性”的一部分。而“可扩展性”根本没有被提及。
都明白(上述内容)了吗?
像这样的列表——而且有很多这样的列表在流传——确实有其用途。它们可以作为有用的检查清单,帮助需求收集者确保没有重要需求被忽略。比独立的列表更有用的是,它们可以作为创建你自己的检查清单的基础,该清单包含你所在领域、行业、组织、产品中所关注的质量属性。质量属性列表也可以作为制定度量标准的基础,尽管这些名称本身对于如何做到这一点几乎没有提供线索。如果“趣味性”在你的系统中是一个重要的关注点,你如何度量它以了解你的系统是否提供了足够的趣味性呢?
像这样的通用列表也有一些缺点。首先,没有一个列表会是完整的。作为一名架构师,你不可避免地会被要求设计一个系统来满足利益相关者的关切,而这种关切是任何列表制定者都没有预见到的。例如,一些作者提到了“可管理性”,它表示系统管理员管理应用程序的难易程度。这可以通过插入用于监控操作以及调试和性能调优的有用工具来实现。我们知道有一个架构是有意识地以留住关键员工并吸引有才华的新员工到美国中西部一个安静地区为目标而设计的。那个系统的架构师谈到要给系统注入“爱荷华(州)适用性”。他们通过引入最先进的技术并给予他们的开发团队广泛的创作自由度来实现这一目标。在任何标准的质量属性列表中找到“爱荷华(州)适用性”都不太可能,但那个质量属性对那个组织来说和其他任何质量属性一样重要。
其次,列表往往引发的争议多于带来的理解。你可能会很有说服力地争辩说“功能正确性”应该是“可靠性”的一部分,或者“可移植性”只是一种“可修改性”,或者“可维护性”是一种“可修改性”(而不是相反情况)。ISO 25010 的编写者显然花费了时间和精力来决定将安全性作为其自身的特性,而不是像前一版本那样将其作为功能性的一个子特性。我们坚信,在进行这些争论上所花费的精力可以更好地用在其他地方。
第三,这些列表往往声称是分类法——也就是说,具有这样一种特殊属性的列表:每个成员都能被准确地归到一个位置。但在这方面,质量属性是出了名的难以明确界定。例如,我们在 第 3 章 中讨论过拒绝服务,它涉及安全性、可用性、性能和易用性等多个方面。
这些观察结果强化了在 第 3 章 中介绍的教训:质量属性名称本身基本上是无用的,最多只是开启对话的引子。此外,花费时间担心哪些质量属性是其他质量属性的子属性几乎是毫无用处的。相反,场景为我们提供了最佳方式,以便在我们谈及质量属性时准确说明我们的意思。
在质量属性标准列表作为检查清单有所帮助的范围内使用它们,但不必拘泥于其术语或结构。并且不要欺骗自己认为这样的检查清单消除了进行更深入分析的需要。
14.3 处理“X 能力”:将新的质量属性纳入考量
假设作为一名架构师,你必须处理一个没有完备知识体系的质量属性,没有像 第 4 章 至 第 13 章 为那些质量属性所提供的那种“汇总资料”。假设你发现自己必须处理诸如“开发可分发性”或“可管理性”甚至“爱荷华(州)适用性”这样的质量属性,你会怎么做?
为新质量属性捕捉场景
第一步是与那些其关注点导致对该质量属性有需求的利益相关者进行面谈。你可以与他们合作,无论是单独还是作为一个团队,来构建一组属性特征描述,以细化该质量属性的含义。例如,你可以将开发可分发性分解为软件分割、软件组合和团队协调等子属性。在进行了这种细化之后,你可以与利益相关者一起制定一组具体的场景,以描述该质量属性的含义。这个过程的一个例子可以在第 22 章中找到,我们在那里描述了构建一个“效用树”的情况。
一旦你有了一组具体的场景,那么你就可以对这些场景集合进行概括。查看你收集的刺激集合、响应集合、响应度量集合等等。通过将通用场景的每个部分都概括为你收集的具体实例,利用这些来构建一个通用场景。
对质量属性进行建模
如果你能构建(或者更好的是,找到)质量属性的概念模型,那么这个基础对于为其创建一组设计方法会很有帮助。这里所说的“模型”,我们的意思不过是对质量属性敏感的参数集以及影响这些参数的架构特征集的一种理解。例如,一个可修改性的模型可能会告诉我们,可修改性是系统中为响应修改而必须更改的位置数量以及这些位置之间相互关联程度的函数。一个性能模型可能会告诉我们,吞吐量是事务工作负载、事务之间的依赖关系以及可以并行处理的事务数量的函数。
图 14.2 展示了一个简单的性能排队模型。此类模型被广泛用于分析各种类型排队系统的延迟和吞吐量,包括制造和服务环境以及计算机系统。
在此模型中,七个参数可能会影响模型预测的延迟:
- 到达率
- 排队规则
- 调度算法
- 服务时间
- 拓扑结构
- 网络带宽
- 路由算法
这些是在此模型中能够影响延迟的仅有的参数。这就是该模型的效力所在。此外,这些参数中的每一个都可能受到各种架构决策的影响。这就是该模型对架构师有用的原因。例如,路由算法可以是固定的,也可以是负载均衡算法。必须选择一种调度算法。拓扑结构可能会因动态添加或移除新服务器而受到影响。等等。
如果你正在创建自己的模型,你的场景集将为你的研究提供信息。其参数可以从触发事件(及其来源)、响应(及其度量)、工件(及其属性)以及环境(及其特征)中推导出来。
为新质量属性组合设计方法
基于模型生成一组机制的过程包括以下步骤:
- 列举模型的参数。
- 对于每个参数,列举能够影响该参数的架构特性(以及实现这些特性的机制)。你可以通过以下方式做到这一点:
- 重新审视你熟悉的一组机制,并自问每个机制如何影响质量属性参数。
- 搜索成功处理此质量属性的设计。你可以搜索你为质量属性所取的名称,但你也可以搜索在将质量属性细化为子属性时所选的术语。
- 搜索关于此质量属性的出版物和博客文章,并尝试概括它们的观察结果和发现。
- 找到该领域的专家并对他们进行访谈,或者简单地写信向他们征求建议。
结果是得到了一份机制列表,在上述示例中是用于控制性能的机制列表,更一般地说,是用于控制模型所关注的质量属性的机制列表。这使得设计问题更易于处理。这份机制列表是有限且相对较小的,因为模型的参数数量是有限的,并且对于每个参数,影响该参数的架构决策数量也是有限的。
14.4 扩展阅读
所有质量属性列表之母可能是在——还能在哪儿呢?——维基百科上的那个列表。很自然地,这个列表可以在“系统质量属性列表”下找到。在本书出版时,你可以尽情浏览 80 多个不同质量属性的定义。我们最喜欢的是“可演示性”,它被很有帮助地定义为具有可演示的特性。谁说你不能相信在互联网上读到的内容呢?
请参阅[Bass 19]的第 8 章,以获取部署管道的质量列表。这些质量包括可追溯性、(部署管道的)可测试性、工具使用以及周期时间。
14.5 问题讨论
1. 不丹王国衡量其国民的幸福度,并且制定政府政策以提高不丹的国民幸福总值(GNH)。了解一下国民幸福总值是如何衡量的(试试grossnationalhappiness.com),然后为“幸福”这一质量属性勾勒一个通用场景,以便你能够表达软件系统具体的幸福需求。
2. 选择一个在 第 4 章 至 第 13 章 中未描述的质量属性。对于该质量属性,整理一组具体的场景来描述其含义。使用该场景集为其构建一个通用场景。
3. 对于你在问题 2 中选择的质量属性,整理一组有助于实现它的设计机制(模式和策略)。
4. 针对“开发成本”这一质量属性重复问题 2 和问题 3,然后针对“运营成本”这一质量属性也重复问题 2 和问题 3。
5. 什么可能会导致你在 第 4 章 至 第 13 章(或者对于任何其他质量属性而言)已经描述的质量属性集合中添加一个策略或模式呢?
6. 讨论你认为开发可分发性如何与性能、可用性、可修改性和可集成性等质量属性进行权衡。
7. 研究一些非软件系统的质量属性列表:例如,一辆好车的品质,或者一个适合交往的好人的品质。在你找到的列表中添加你自己选择的品质。
8. 开发时的策略与分离和封装职责有关。性能策略与将事物整合在一起有关。这就是它们一直存在冲突的原因。情况一定总是如此吗?是否有一种有原则的方法来量化这种权衡呢?
9. 是否存在策略分类法?化学家有元素周期表和分子相互作用定律,原子物理学家有亚原子粒子目录以及它们碰撞时会发生什么的定律,药理学家有化学物质目录以及它们与受体和代谢系统相互作用的定律等等。策略的对应物是什么呢?并且对于它们的相互作用是否存在定律呢?
10. 安全性是一种质量属性,它对计算机外部物理世界中发生的过程特别敏感:应用补丁的过程、选择和保护密码的过程、物理保护计算机和数据所在设施的过程、决定是否信任一款导入软件的过程、决定是否信任一名人类开发者或用户的过程等等。对于性能来说,相应的重要过程是什么呢?或者对于可用性呢?存在这样的过程吗?为什么安全性对过程如此敏感呢?过程应该是质量属性结构的一部分还是与它正交呢?
11. 以下列表中每对质量属性之间的关系是什么?
- 性能和安全性
- 安全性和可构建性
- 能效性和上市时间