目录
开发分布性 Development Distributability
架构的概念完整性 Conceptual Integrity of the Architectur
质量不是一种行为,而是一种习惯。
——亚里士多德
第5-11章分别涉及了对软件系统重要的特定质量属性。每一章都讨论了如何定义特定的质量属性,提供了关于该质量属性的一般情境,并展示了如何编写具体的情境以表达有关该质量属性的精确含义。每一章还提供了一系列在架构中实现该质量属性的技术。简而言之,每一章都呈现了一种用于规定和设计以实现特定质量属性的作品集。
这七章涵盖了七种最重要的质量属性,就其在现代软件依赖系统中的出现而言。然而,毫无疑问,七只是开始涉及您在处理的软件系统中可能需要的质量属性的冰山一角。
成本是一种质量属性吗?它不是技术性的质量属性,但它肯定会影响使用适应性。我们将在第23章中考虑经济因素。
本章将简要介绍其他一些质量属性,一种“B级”质量属性。但更重要的是,它将展示如何为未在我们的列表中涵盖的质量属性构建相同类型的规范或设计作品集。
其它重要的质量属性
除了我们在第5-11章中深入探讨的质量属性之外,还有一些常见的其他质量属性,包括可变性、可移植性、开发分布性、可扩展性和弹性、可部署性、移动性和可监控性。我们在第12.3节中讨论了“绿色”计算。
可变性 Variability
可变性是可修改性的一种特殊形式。它指的是系统及其支持文档(例如需求、测试计划和配置规范)支持生成一组与预先计划方式不同的变体。在软件产品线中,可变性是一个特别重要的质量属性(这将在第25章中深入探讨),在这里它意味着核心资产适应产品线范围内不同产品上下文的能力。软件产品线中可变性的目标是使在一段时间内轻松构建和维护产品线中的产品。可变性的情境将处理变体的绑定时间和实现它所需的人力。
可移植性 Portability
可移植性也是可修改性的一种特殊形式。可移植性是指构建为在一个平台上运行的软件如何轻松更改以在不同平台上运行。通过在软件中最小化对平台的依赖性,将依赖性隔离到确定位置,并编写软件以在“虚拟机”上运行(例如Java虚拟机),以将所有平台依赖性封装在其中来实现可移植性。描述可移植性的情境将处理将软件移植到新平台时所需的努力水平或需要更改的软件中的位置数。
开发分布性 Development Distributability
开发分布性是指设计软件以支持分布式软件开发的质量。许多系统如今都是使用全球分布的团队开发的。在与分布式团队一起开发时,必须克服的一个问题是协调他们的活动。系统应该被设计为使团队之间的协调最小化。这种最小化的协调需要在代码和数据模型中都实现。在相互通信的模块上工作的团队可能需要协商这些模块的接口。当一个模块被许多其他由不同团队开发的模块使用时,通信和协商变得更加复杂和繁琐。开发分布性的情境将处理正在开发的系统的通信结构和数据模型的兼容性,以及执行开发的组织的协调机制。
可伸缩性 Scalability
可伸缩性分为水平可伸缩性和垂直可伸缩性两种类型。水平可伸缩性(横向扩展)指的是向逻辑单元添加更多资源,例如将另一个服务器添加到服务器集群中。垂直可伸缩性(纵向扩展)指的是向物理单元添加更多资源,例如将更多内存添加到单台计算机上。对于任何类型的伸缩,出现的问题是如何有效地利用额外的资源。有效意味着额外的资源导致某些系统质量得到可衡量的改善,不需要过多的努力来添加,也不会干扰操作。在云环境中,水平可伸缩性称为弹性。弹性是一个属性,使客户能够从资源池中添加或删除虚拟机(有关此类环境的进一步讨论,请参见第26章)。这些虚拟机托管在由云提供商管理的上万个物理机器上。可伸缩性的情境将处理添加或删除资源的影响,并且措施将反映相关的可用性和分配给现有和新资源的负载。
可部署性 Deployability
可部署性涉及可执行文件如何到达主机平台以及在随后如何调用它。部署软件涉及的问题之一是:它如何到达它的主机(推送,其中更新未经用户请求地发送到用户,或拉取,其中用户必须显式请求更新)?它如何集成到现有系统中?在现有系统正在执行时是否可以完成这个过程?移动系统在更新方面有自己的问题,因为会考虑带宽问题。部署情境将处理更新的类型(推送或拉取),更新的形式(媒介,例如DVD或互联网下载,以及包装,例如可执行文件,应用程序或插件),它集成到现有系统中的结果,执行该过程的效率,以及相关的风险。
移动性 Mobility
移动性处理平台的移动和支持(例如,大小、显示类型、输入设备类型、带宽的可用性和体积,以及电池续航时间)的问题。移动性的问题包括电池管理、断开连接一段时间后的重新连接,以及支持多个平台的多个用户界面所需的数量。情境将涉及指定移动性或各种可用性的期望效果。情境也可能涉及到可变性,即将相同的软件部署在多个(可能是截然不同的)平台上。
可监控性 Mobility
可监控性涉及操作人员在系统执行时监控系统
的能力。队列长度、平均事务处理时间和各种组件的健康状况等项目应该对操作人员可见,以便他们在出现潜在问题时采取纠正措施。情境将涉及潜在问题及其对操作员的可见性以及潜在纠正措施。翻译完毕。
安全性 Safety
2009年,西伯利亚舒申斯卡水电站的一名员工通过网络远程发送命令,意外地激活了一个未使用的涡轮机。离线涡轮机产生了“水锤”,导致工厂被淹没,然后被摧毁,并导致数十名工人丧生。
软件可能导致人员死亡的想法曾经只存在于烂俗的电脑暴走科幻小说的领域。可悲的是,它没有停留在那里。随着软件控制着我们生活中越来越多的设备,软件安全性已成为一个重要关切。
安全性不仅仅是软件的问题,而是任何可能影响其环境的系统的问题。因此,它在第12.3节中提到,我们将在该节中讨论系统质量属性。但是有一些完全在软件领域内解决安全性的方法,这就是我们在这里讨论它的原因。
软件安全性涉及软件避免进入导致或导致损坏、伤害或生命丧失的状态的能力,以及在进入糟糕状态时恢复和限制损害的能力。换另一种方式来说,安全性关注的是预防危险故障以及从危险故障中恢复。因此,与安全相关的架构问题与可用性几乎完全相同,因为可用性也与避免和从故障中恢复相关。因此,安全性的策略在很大程度上与可用性的策略重叠。两者都包括防止故障和检测和从发生的故障中恢复的策略。
安全性与可靠性不同。系统可以是可靠的(与其规范一致),但仍然不安全(例如,当规范忽略导致不安全行为的条件时)。实际上,要想生产安全的软件,仔细注意安全关键软件的规范可能是最有效的事情。如果软件没有以这些问题为基础进行设计,将无法检测、预防或减轻故障和危险。安全性通常通过执行故障模式和影响分析、危险分析和故障树分析来进行工程化。这些技术旨在发现可能由系统运行引起的潜在危险,并提供应对这些危险的计划。
其它类型的质量属性
除了我们在关于质量属性的讨论中主要关注的产品质量之外,还有其他类型的质量属性,用于衡量某种事物的“好坏”而不仅仅是最终产品。以下是三种:
架构的概念完整性 Conceptual Integrity of the Architectur
概念完整性指的是架构设计的一致性,它有助于理解架构,并减少混淆或错误。概念完整性要求架构中的相同事物以相同的方式进行。在具有概念完整性的架构中,越简单越好。例如,组件之间传递信息有无数种方式:消息、数据结构、事件信号等等。具有概念完整性的架构只提供一种方式,并只在有强制原因时提供替代方案。同样,组件应该以相同的方式报告和处理错误,以相同的方式记录事件或事务,以相同的方式与用户交互,等等。
使用质量 Quality in Use
ISO/IEC 25010,我们在第12.4节中讨论了,包含了与各种利益相关方使用系统相关的一类质量。例如,上市时间是系统的重要特征,但它无法从对产品本身的检查中分辨出来。在这一类别中的一些质量包括:
- 效能:这是指构建系统是否正确(系统按照其要求执行)与构建正确的系统(系统按用户希望的方式执行)之间的区别。效能是系统是否正确的度量。
- 效率:开发系统所需的工作和时间。换句话说,架构对项目成本和进度的影响如何?不同的架构选择是否会导致系统更快或更便宜地完成?效率可以包括开发人员的培训时间;使用对现有员工陌生的技术的架构不容易构建。架构是否适合组织,与其经验和可用的支持基础设施(如测试设施或开发环境)是否一致?
- 风险自由:产品或系统对经济状况、人类生命、健康或环境产生影响的程度。
效率的一个特殊情况是在进行更改后构建系统的难易程度(即编译和汇编)。这在测试期间变得至关重要。如果重新编译的过程需要数小时或过夜,将导致进度受损。架构师可以通过管理模块之间的依赖关系来控制这一点。如果架构师不这样做,那么经常会发生的情况是一些充满朝气的开发人员早早地编写了一个make文件,它有效,然后人们不断添加功能。最终,项目会出现一个需要七小时才能完成的编译步骤,以及非常不满的集成和测试人员,因为他们已经落后进度(因为他们总是)。
市场性 Marketability
架构的市场性是另一个需要关注的质量属性。某些系统以其架构而闻名,这些架构有时具有独立于它们为系统带来的其他质量属性的意义。构建基于云的系统的当前狂热已经教会了我们,架构的认知对比架构带来的质量更重要。许多组织感到必须构建基于云的系统(或其他技术dujour),无论这是否是正确的技术选择。
软件质量属性和系统质量属性
依赖嵌入式软件的物理系统,例如飞机、汽车或厨房电器,被设计来满足一系列完全不同的质量属性:重量、尺寸、电耗、功率输出、污染排放、抗天气性、电池寿命等等。对于许多这些系统,安全性是排在首位的(请参见侧栏)。
有时,软件架构可能会对系统的质量属性产生令人意外的影响。例如,效率低下的软件可能需要额外的内存、更快的处理器、更大的电池,甚至额外的处理器。额外的处理器会增加系统的功耗、重量、所需的机柜空间,当然也会增加费用。
绿色计算是一个越来越受关注的问题。最近,关于谷歌的大规模处理器农场排放多少温室气体进入大气的争议。根据每日产量和每日请求的数量,可以估算每次要求谷歌执行搜索时你排放了多少温室气体。(目前的估计范围从0.2克到7克二氧化碳。)绿色计算正成为风潮。Eve Troeh 在美国公共媒体节目 "Marketplace"(2011年7月5日)中报导道:
根据美国环保署的数据,如今美国所有电力中有2%用于数据中心。电力已经成为处理数据的最大成本,超过了用于处理数据的设备,也超过了设备所在建筑的成本... 谷歌正在制造可以漂浮在离岸的数据服务器,通过海风冷却。惠普计划在农场附近放置数据服务器,并使用牛粪产生的甲烷气体来为其供电。
这里的教训是,如果你是位于更大系统中的软件架构师,你需要了解对容纳系统的重要质量属性,以及与系统架构师和工程师一起合作,了解你的软件架构如何有助于实现这些质量属性。
软件和系统质量之间的模糊边界
这是一本关于软件架构的书,因此我们从软件架构师的角度来处理质量属性。但您可能已经注意到,软件架构师能够为其带来的质量属性受到了运行软件的系统架构的限制。
例如:
• 软件的性能基本上受到运行它的计算机的性能的制约。无论您如何设计软件,您都不能在Grampa的Commodore 64上运行最新的全球气象预测模型,以便知道明天是否会下雨。
• 物理安全可能比软件安全更重要且更有效,以防止欺诈和盗窃。如果您不相信这一点,可以将笔记本电脑的密码写在一张纸条上,将其贴在笔记本电脑上,然后将其留在没有关闭窗户的汽车中。(实际上,不要这么做。把它当作一个思维实验。)
• 老实说,具有小于信用卡大小的屏幕和葡萄干大小的按键的设备用于网页浏览的可用性如何?对我来说,软件和系统之间的界限在安全领域最不明确。认为由0和1组成的软件字符串可能会导致杀人、伤害或破坏仍然是一种不自然的想法。当然,0和1本身不会直接制造混乱。至少不是直接。问题出在它们连接的对象上。软件以及它运行的系统在能够造成破坏之前必须以某种方式连接到外部世界。这是好消息。坏消息是,好消息并不那么好。
软件始终与外部世界相连接。如果您的程序对外部世界没有任何可观察的影响,那它可能毫无用处。
有一些臭名昭著的与软件相关的事故。正文中提到的西伯利亚水电站灾难、Therac-25致命辐射过量、阿丽亚娜5爆炸以及其他数十起不太知名的事故都是因为软件是系统的一部分,包括涡轮机、X射线发射器或火箭的控制装置等等。在这些情况下,有缺陷的软件命令系统中的某些硬件采取灾难性的行动,而硬件只是顺从了命令。执行器是将硬件与软件连接的设备,它们是0和1的世界与运动和控制世界之间的桥梁。将数字值发送给执行器(或将位字符串写入与执行器对应的硬件寄存器),该值将被转换为某种机械动作,或好或坏。
但并非所有软件相关的灾难都需要连接到执行器。有时,计算机所需做的就是向其操作人员发送错误的信息。1983年9月,一颗苏联卫星向其地面系统计算机发送了数据,该计算机将这些数据解释为从美国发射到莫斯科的导弹。几秒钟后,计算机报告第二颗导弹正在飞行。不久后,第三颗、第四颗,然后是第五颗出现。苏联战略火箭部队中校Stanislav Yevgrafovich Petrov做出了忽略警告系统的惊人决定,认为它是错误的。他认为美国不太可能只发射了几枚导弹,从而引发全面的报复毁灭。他决定等待一段时间,以查看导弹是否真实存在,也就是说,以查看他的国家首都是否会被焚毁。正如我们所知,最后并没有发生。苏联系统误将少见的阳光条件误认为是正在飞行的导弹。类似的错误也在美国一侧发生。
当然,人类并不总是做出正确的决定。2009年6月1日这个黑暗多风的夜晚,从里约热内卢飞往巴黎的法国航空447航班坠入大西洋,机上
所有人都遇难。空中客车A-330的飞行记录仪直到2011年5月才被找到,截至本书出版,飞行员似乎从未知道飞机进入了高空失速状态。测量空速的传感器已被冰堵塞,因此不可靠。在这种情况下,软件需要在此情况下解除自动驾驶,而它也确实解除了。飞行员认为飞机速度太快(存在结构失效的危险)实际上飞机速度太慢(正在下降)。在从38000英尺跃升三分钟以上的整个过程中,飞行员一直试图抬起机头并将油门拉回以降低速度。可以肯定的是,A-330的失速警告系统工作方式增加了混淆。当系统检测到失速时,会发出大声的警报。当计算机"认为"攻击角测量无效时,计算机会停用失速警告。这可能发生在空速读数非常低的情况下。这正是发生在法国航空447上的情况:前进速度降至60节以下,进攻角非常高。由于飞行控制软件的规则,失速警告多次启动和停止。更糟糕的是,每当飞行员将机头下降一点(增加了空速并使读数进入"有效"范围,但仍处于失速状态),然后拉回时,警告就会停止。也就是说,做正确的事情导致了错误的反馈,反之亦然。
这是一个不安全的系统,还是一个安全的系统操作不当?最终由法院来决定。
能够对我们造成身体伤害的软件是我们现代生活的现实。有时,软件和身体伤害之间的联系是直接的,如阿丽亚娜的例子,有时则更加微弱,如法国航空447的例子。但作为软件专业人员,我们不能以我们的软件实际上无法造成伤害来为避难所,就像在拥挤的剧院中喊 "火!"的人不能声称造成伤害的是人群的踩踏,而不是呼喊声。
——PCC
使用标准的质量属性列表与否
架构师可以随时使用各种软件系统质量属性的标准列表。一个具有冗长标题的标准是"ISO/IEC FCD 25010:系统和软件工程-系统和软件产品质量要求与评估(SQuaRE)系统和软件质量模型"。这个标准将质量属性分为支持"使用中的质量"模型和支持"产品质量"模型的属性。在某些地方,这种划分可能有些牵强,但它无疑开始了对各种各样的质量属性进行划分和研究。
请参见图12.1,了解这些质量属性的范围。
标准列出了以下处理产品质量的质量属性:
- 功能适用性。在指定条件下使用时,产品或系统提供满足陈述和隐含需求的功能的程度。
- 性能效率。在指定条件下,性能相对于使用的资源量。
- 兼容性。产品、系统或组件能够在共享相同硬件或软件环境的情况下与其他产品、系统或组件交换信息和/或执行其所需功能的程度。
- 可用性。产品或系统能够由指定的用户在指定的使用背景下以有效性、效率和满意度实现指定目标的程度。
- 可靠性。在指定条件下,系统、产品或组件在指定的时间段内执行指定功能的程度。
- 安全性。产品或系统保护信息和数据的程度,以使具有适当授权类型和级别的人员或其他产品或系统具有数据访问的程度。
- 可维护性。由预期的维护人员修改产品或系统的效果和效率程度。
- 可移植性。系统、产品或组件能够从一个硬件、软件或其他操作或使用环境转移到另一个环境的效果和效率程度。
在ISO 250 10中,这些“质量特征”都由“质量子特征”组成(例如,不可否认是安全的一个子特征)。标准以这种方式详细定义了近五十个独立的质量子特征。它为我们定义了“愉悦”和“舒适”的特征。它区分了“功能正确性”和“功能完整性”,然后再加上“功能适用性”。要展示“兼容性”,系统必须具有“互操作性”或“共存性”。 “可用性”是一个产品质量,而不是质量属性的一部分,尽管它包括“满意度”,满意度是一种质量属性。 “可修改性”和“可测试性”都属于“可维护性”。 “可修改性”是一种实现质量的策略,而不是自己的目标。 “可用性”是“可靠性”的一部分。 “互操作性”是“兼容性”的一部分。而且“可扩展性”根本没有提到。
知道了吗?
像这样的列表有一定的作用。它们可以帮助需求收集者制定检查清单,以确保没有遗漏任何重要的需求。与独立的列表一样有用,它们可以作为创建自己的检查清单的基础,其中包含您领域、行业、组织和产品中关注的质量属性。质量属性列表还可以作为建立度量的基础。如果“愉悦”在您的系统中非常重要,那么如何衡量它以了解系统是否提供足够多的愉悦?
然而,这些通用列表也有缺点。首先,没有任何列表会是完整的。作为架构师,您将被要求设计一个系统以满足任何列表制作者未能预见的利益相关者关切点。例如,有些作者谈到“可管理性”,它表达了系统管理员管理应用程序的难易程度。这可以通过插入用于监视操作以及用于调试和性能调整的有用工具来实现。我们知道有一个架构是有意目标的,即保留关键员工并吸引人才,以应对美国中西部一个安静地区的挑战。该系统的架构师们谈到了如何赋予系统“低性能”。他们通过引入尖端技术,并给予他们的开发团队广泛的创造性自由来实现这一目标。祝您好运,找到“低性能”在任何标准的质量属性列表中,但是对于该组织来说,这个QA与其他任何质量属性一样重要。
其次,这些列表通常引发的争议多于理解。您可能有令人信服的论点,即“功能正确性”应该成为“可靠性”的一部分,或者“可移植性”只是一种“可修改性”,或者“可维护性”是“可修改性”的一种类型(而不是反过来)。 ISO 250 10的作者显然花了时间和精力决定使安全性成为其自己的特性,而不是功能的子特性,尽管它在以前的版本中是功能的子特性。我们认为,在做出这些争论方面花费的精力可以更好地用在其他地方。
第三,这些列表通常宣称是分类法,这是一种具有特殊属性的列表,每个成员都可以分配到精确一个位置。质量属性在这方面极具挑战性。我们在第4章中讨论了服务拒绝作为安全性、可用性、性能和可用性的一部分。
最后,这些列表迫使架构师关注列表中的每个质量属性,即使最终决定特定质量属性与其系统无关。知道如何快速判断某个质量属性与特定系统无关,是随着时间获得的技能。
这些观察结果强调了第4章中介绍的教训,即单独的质量属性名称本身几乎是无用的,最多只能作为开始对话的邀请;花时间担心哪些质量是其他质量的子质量也几乎是无用的;情景提供了我们明确定义我们在谈到质量属性时的含义的最佳方式。
在某种程度上使用标准的质量属性列表作为检查清单,但不要觉得必须盲目遵循它们的术语。
处理“X-ability”:引入新的质量属性
假设作为一名架构师,您必须处理一个没有紧凑的知识体系,没有像第5-11章为那七个质量属性提供的“作品集”那样的质量属性。假设您发现自己必须处理像“绿色计算”、“可管理性”甚至“低性能”这样的质量属性?您会怎么做?
捕捉新质量属性的场景
首先要做的是采访那些由于利益相关者的关切而需要这个质量属性的人。您可以与他们合作,无论是单独还是作为一个团队,以建立一组属性特征,以进一步明确QA的含义。例如,安全性通常被分解为诸如机密性、完整性、可用性等方面的问题。在经过这种精化之后,您可以与利益相关者合作,制定一组特定场景,以描述QA的含义。
一旦您有了一组特定场景,那么您可以开始将集合概括化。查看您收集的刺激集、响应集、响应度量等等。使用这些内容构建一个一般性场景,通过使一般场景的每个部分成为您收集的特定实例的一般化来实现这一目标。
根据我们的经验,到目前为止,前述步骤通常需要大约半天的时间。
组装新质量属性的设计方法
在拥有QA的指导场景集之后,您可以组装一组用于处理该QA的设计方法。您可以通过以下方式实现:
- 重新审视您熟悉的模式库,然后询问每个模式如何影响您感兴趣的QA。
- 搜索需要处理该QA的设计。您可以根据您为QA本身指定的名称进行搜索,但您还可以搜索在将QA细化为子属性特征时选择的术语(例如,对于安全性QA,可选择“保密性”)。
- 找到这个领域的专家,与他们进行访谈,或者只是写信向他们寻求建议。
- 使用一般场景来尝试列出用于生成响应的设计方法清单。
- 使用一般场景来列出问题架构无法生成所需响应的方式,然后考虑设计方法以避免这些情况。
对新的质量属性建模
如果您可以建立质量属性的概念模型,这有助于创建一组用于处理它的设计方法。通过“模型”,我们并不是指更多的东西,只是理解质量属性敏感的参数集。例如,可修改性的模型可能告诉我们,可修改性取决于系统中需要在修改响应中更改的位置数量以及这些位置之间的互联性。性能的模型可能告诉我们,吞吐量取决于事务工作负载、事务之间的依赖关系以及可以并行处理的事务数量。
一旦您为QA建立了模型,然后可以开始列出可供您打磨每个相关参数以符合您的愿望的设计方法(策略和模式)。
组装新质量属性的战术集
可以用于导出任何质量属性的战术的两个来源:模型和专家。图12.2显示了性能的排队模型。这种模型广泛用于分析各种类型的排队系统的延迟和吞吐量,包括制造和服务环境以及计算机系统。
在这个模型中,有七个参数可以影响模型预测的延迟:
- 到达率
- 排队规则
- 调度算法
- 服务时间
- 拓扑结构
- 网络带宽
- 路由算法
这些是唯一可以在该模型中影响延迟的参数。这是使模型强大的原因。此外,每个这些参数都可以受到各种架构决策的影响。这是使模型对架构师有用的原因。例如,路由算法可以固定或者可以是一个负载均衡算法。必须选择一个调度算法。拓扑结构可以通过动态添加或删除新服务器来受到影响,等等。
基于模型生成战术的过程如下:
- 枚举模型的参数
- 对于每个参数,枚举可以影响该参数的架构决策
结果是一份战术清单,用于在示例情况下控制性能,以及在更一般情况下控制模型关注的质量属性。这使得设计问题似乎更容易解决。这份战术清单是有限的,而且相当小,因为模型的参数数量是有限的,对于每个参数,影响该参数的架构决策的数量是有限的。
从模型中导出战术是可以的,只要所涉及的质量属性有一个模型。不幸的是,这类模型的数量有限,而且是一个活跃的研究领域。例如,对于可用性或安全性等质量属性,目前还没有好的架构模型。在没有模型的情况下,我们有四种方法来整理战术:
- 我们采访了领域的专家,询问他们作为架构师如何改进质量属性的响应。
- 我们研究了那些被吹捧为具有高可用性(或可测试性或我们关注的其他战术)的系统。
- 我们搜索相关的设计文献,寻找设计中的共同主题。
- 我们检查记录下来的架构模式,寻找它们实现的质量属性响应。
为新质量属性构建设计检查表
最后,审查第4章中的七类设计决策,并询问自己(或您的专家)如何将您关注的新质量属性专门用于这些类别。特别是,考虑审查软件架构,并尝试弄清楚它在这七个类别中如何满足新质量的要求。您会向该系统的架构师提出哪些问题,以了解设计是如何努力实现新的质量属性的?这些问题构成了设计检查表的基础。