5.2评估软件架构

一个软件项目涉及两种可以评估的“事物”: • 过程 - 例如,开发或操作过程 • 工件,如需求、源代码或其他文档 其中一些工件(如源代码)可以进行定量评估(即以数字表示),而其他不能用数字评估的则根据其属性或质量进行评估。

5.2.1 定性评估

存在各种用于评估软件架构质量的属性和模型,每个都侧重于系统的不同方面。这些质量模型构成了评估和分析的基础,因为它们涉及项目的质量要求。

在对架构进行定性评估期间,各种信息来源可能会有所帮助 - 例如,需求、质量树和场景、架构和设计模型、源代码和指标。 5.2.1.1 DIN ISO / IEC 25010 DIN ISO/IEC 9126 [ISO/IEC 9126] 将软件质量定义为软件产品的与满足定义和预设要求的适合性相关的特征和相关值的整体。 在 2005 年,它被新的 DIN ISO/IEC 25010 [ISO/IEC 25010] 所取代,这是 250xx 系列规范的一部分。其正式名称是系统和软件工程 - 系统和软件质量要求和评估(SQuaRE) - 系统和软件质量模型。

为了确保成功,质量应持续得到保证。对于面向对象的软件开发,这包括审查、单元和回归测试以及架构分析。

质量模型使用细节和规范使软件质量的概念可测量。 5.2.1.2 质量特性 在新的 ISO/IEC 25010 标准中,ISO/IEC 9126 中列出的六个主要特性补充了新的特性安全性和兼容性。添加了一些子特性,并且其他特性进行了重命名: • 功能的适用性 软件是否具有足够的功能来满足指定和预设的要求? • 可靠性 软件在特定条件下在特定时间段内能否保持其性能水平? • 可用性 程序是否易于学习和使用?对于用户来说,软件的吸引力和用户友好程度如何? • 性能效率 就资源、查询和处理响应时间以及存储空间而言,软件对于解决特定问题的经济性如何? • 安全 性 数据保护的效果如何?未经授权的人员或系统是否能够读取或修改数据?是否允许所有授权人员或系统访问数据? • 兼容性 两个或多个系统或组件能否在共享相同的硬件或软件环境时相互交换信息和/或执行其所需的功能? • 可维护性 纠错、实现改进或适应环境变化所涉及的工作有多少?可重用性水平有多高?在不引入不良副作用的情况下,软件在可变性方面的稳定性如何? • 可移植性 软件能否在其他(硬件和软件)系统上使用? 这些主要特性中的每一个都通过子特性进行了细化(见表 5 - 1)。

表5-1符合ISO/IEC 25010 [ISO/IEC 25010]的质量特性

5.2.1.3其它质量特性 另一个质量特性的例子是可扩展性,它描述了硬件和软件对不断增加的需求数量的适应性。这里区分了纵向扩展和横向扩展。纵向扩展是用性能更强的解决方案替换系统(例如,升级服务器或用更强大的型号替换),而在横向扩展的情况下,向系统添加额外的硬件资源(例如,额外的服务器)。根据其目的,可能还有其他“特性”作为软件系统的质量特性与利益相关者相关。 尽管它们通常被认为是不言而喻的,但相关的质量特性应明确记录。只有明确记录的特性才能建设性地用于提高质量并确保透明度。由于软件架构师对整个系统的质量负责,因此呼吁明确和具体的质量特性或积极修改现有的质量特性是至关重要的。 5.2.1.4 特定质量特征的影响 系统的各种质量特性或属性可能会对彼此产生广泛的影响。一些例子: • 简单性增加了可理解性。 • 安全性可能会降低可用性 - 例如,如果特定功能仅在特定网络内可用。 • 灵活性可能会降低可测试性,因为增加的灵活性(例如,运行时可配置性)可能会导致需要更多测试的更复杂系统。 • 在大多数情况下,适应性和灵活性与提高性能的要求相冲突。 • 提高性能的要求反过来又可能阻碍按时完成。 由于这些原因,您通常需要为每个特定的软件平衡各个质量要求的优先级。 5.2.1.5 满足质量要求的策略和实践 那么我们如何满足特定的质量特性呢? 对于为特定质量特性开发解决方案策略,没有通用的方法。作为架构师,您必须根据个人情况和上下文,在开发视图和技术概念的同时制定适当的措施。 以下部分提供了一些实现特定质量特性的示例策略和实践。这些策略通常会有所帮助,但并非在所有情况下都有效。 正如已经解释的那样,个别质量特性可能相互影响。对提高性能的渴望可能会影响系统的灵活性、存储空间要求或按时完成。在这种情况下,以下策略可能会有所帮助: • 进行负载测试 • 提供额外的硬件(例如,更多的内存) • 放弃分布式 • 引入冗余 • 减少系统组件间的通信 • 降低系统灵活性

当然,这个列表并不详尽。在某些情况下,通过分布式可以提高性能。在另一个例子中,增加的灵活性可以导致运行时优化器提高性能。 正如已经解释的那样,对增加灵活性和适应性的要求通常与提高性能的要求相冲突。因此,您需要询问系统的哪个方面需要更灵活。这可能是: • 功能 • 数据结构或数据模型 • 外部软件 • 与其他系统的接口 • 用户界面 • 目标平台

这个问题的答案可以帮助缩小所需灵活性的范围。然后,您可以开发各种场景来检查替代架构的适用性。 为了提高系统的灵活性,以下措施可能会有所帮助: • 使用“信息隐藏” o 向其他组件隐藏一个组件的内部细节 o 引入额外的抽象层次 • 减少依赖 • 使更改尽可能本地化,并限制在最少数量的构建块中 • 尽可能地将系统元素彼此解耦 o 始终让构建块通过接口进行通信 o 使用适配器、facades或代理来解耦构建块 • 增加代码的可理解性 然而,所有这些策略都有其局限性,并不是在所有情况下都有效。它们只是为了传达在这里如何实现特定质量特性的基本思路。 另一个重要且值得一提的要点是可追溯性。这是面向质量的软件开发不可或缺的重要特性。所有系统需求必须在正向和反向都是可追溯的 - 即从其来源(通过其描述、规范和实现)到其验证。 要实现可追溯性,以下属性是必要的: • 所有需求的唯一标识 • 选择信息收集和管理的性质、时间、责任和工具支持。

5.2.2 定量评估

除了定性评估外,定量评估以数字方式衡量架构的工件。如果持续进行并长期记录,这些测量可以很好地指示结构变化。然而,它们对于系统的可操作性或运行时质量不提供信息。为了具有可比性,定量评估的结果还需要功能和技术上下文。但是,软件(特别是源代码)的定量评估有助于识别系统内的关键元素。 架构质量保证的定量方法包括: • 度量和评估架构方面的指标,例如输入和输出依赖关系,或复杂性(圈复杂度) • 专注于流程的分析(例如,变更频率的分析) • 检查架构正确实现的分析(例如,通过检查代码中的架构合规性) • 针对软件存储库的分析(例如,检测重复代码)

5.2.2.1检查架构合规性 设计和实现受到系统软件架构对它们施加的特定限制。例如,架构的各个级别限制了源代码中允许的关系和导入能力。因此,所谓的“架构标准”也得到遵守,并且设计和实现适应架构是很重要的。然而,检查对架构标准的遵守情况并非易事。根据项目的性质和系统的规模,可能涉及各种各样的不同架构标准。 架构有效地形成了软件系统的框架(或基本结构),并对其设计和实现施加限制。例如,架构的逻辑级别限制了 UML 设计模型中可能的关系数量以及源代码中类之间的依赖关系。 有一系列工具可用于检查架构标准和评估架构。这些工具可以配置为根据预定义的架构标准评估代码的合规性。 第 6 章更详细地讨论了一些静态分析工具。

5.2.2.2 指标 项目及其源代码可以确定大量的指标。以下是一些示例: • 需求 o 每单位时间变更的需求数量 • 源代码 o 依赖程度(耦合度) o 代码行数 o 注释数量与程序行数的关系 o 静态方法的数量 o 复杂度(可能的执行路径——关于圈复杂度,参见5.2.2.3节) o 每个类的方法数量 o 继承深度 • 软件生产过程 o 单位时间内实现/测试的功能数量 o 单位时间内新增代码行数 o 会议时间与总工作时间的关系 o 预计工作天数与所需工作天数的关系(每个工件) o 经理、开发人员和测试人员的比例 • 错误 o 纠正一个错误的平均时间 o 每个包发现的错误数 • 测试 o 测试用例数量 o 每个类/包的测试用例数量 o 每个需求的测试用例数(测试覆盖率) • 设计 o 传入的依赖关系 o 传出的依赖关系 o 不稳定 o 抽象性 o 距离 • 系统(全部或部分完成) o 性能特征,如资源消耗或处理特定功能或用例所需的时间

5.2.2.3 圈复杂度 圈复杂度也被称为麦凯布度量(M),由托马斯·J·麦凯布于 1976 年提出[McC76]。

它显示了通过程序源代码的线性独立路径的数量,并使用以下公式计算: e−n + 2 p e是图的边的数量,n是图中节点的数量,p是独立控制流图的数量(图/函数/过程)。 McCabe值是对模块复杂性的度量。它表示通过模块的可能路径数量的下限和覆盖控制流图所有边所需的测试用例数量的上限。 一般来说,低圈复杂度意味着模块易于理解、测试和维护。高圈复杂度意味着模块复杂且难以测试。然而,如果复杂度难以降低或者尽管麦凯布值较高但模块易于理解(例如,由于大量的 switch 语句),也可以抑制过高圈复杂度的警告。

Last updated