本系列文章通过逐章回答《Fundamentals of Software Architecture》(下文简称 FOSA)一书中的课后思考题,来深入理解书中的核心概念和理论,从而提升我们的软件架构设计能力。本篇为第四章内容。

本章的课后题是:

  1. What three criteria must an attribute meet to be considered an architecture characteristic?

    一个属性要被认定为架构特征,必须满足哪三个条件?

  2. What is the difference between an implicit characteristic and an explicit one? Provide an example of each.

    隐性特征和显性特征的区别是什么?请分别举一个例子。

  3. Provide an example of an operational characteristic.

    提供一个操作特性的例子。

  4. Provide an example of a structural characteristic.

    提供一个结构特性的例子。

  5. Provide an example of a cross-cutting characteristic.

    提供一个交叉特性的例子。

  6. Which architecture characteristic is more important to strive for—availability or performance?

    在架构特性中,更应努力追求的是可用性还是性能?


架构特征定义

一个属性要成为架构特征(Architecture Characteristics),需至少满足 3 个条件:

  1. 指定非领域设计考量:架构特征关注的是应用程序"如何"实现需求以及做出某些选择"为何"的原因,而不是应用程序"应该做什么"的业务需求。例如,性能水平通常不会出现在需求文档中,但却是重要的架构特征。
  2. 影响设计的某个结构方面:如果一个架构特征需要特殊结构考虑才能成功,那么它就会上升到架构特征的层面。例如,一般的安全性对于几乎所有项目都是必需的,但当需要设计特定的模块、组件或服务来隔离关键安全问题时,安全才成为一个架构特征。
  3. 对应用程序的成功至关重要:应用程序可以支持大量的架构特征,但并非所有都应该被支持。支持每个架构特征都会增加设计的复杂性,因此,架构师的关键任务是选择最少的、对应用程序成功至关重要或重要的架构特征,而不是尽可能多的。

显性 & 隐性

  • 显性架构特征 (Explicit Architecture Characteristics) 是在需求规范中明确列出的,作为必要设计的一部分。它们通常直接出现在需求文档或其他具体说明中。

    在书中的 Silicon Sandwiches 的案例中,用户数量(“当前数千,未来可能数百万”)就隐含地要求了可伸缩性 (Scalability),即在不严重降低性能的情况下处理大量并发用户的能力。虽然需求没有明确提出可伸缩性,但从用户数量的描述中可以推断出来

  • 隐性架构特征 (Implicit Architecture Characteristics) 很少出现在需求文档中,但它们对于项目的成功是必需的。架构师必须利用他们对问题领域的知识,在分析阶段发现这些特征。

    可用性 (Availability) 是一种隐性特征,它确保用户可以访问系统。与可用性密切相关的是可靠性 (Reliability),它确保网站在交互过程中保持正常运行,不会出现连接中断等问题。这些特征通常不会在设计文档中明确指定,但对于几乎所有应用程序都至关重要。

操作特性

操作性架构特性涵盖了系统的运行能力,例如性能、可伸缩性、弹性、可用性和可靠性等。这些特性通常与运营和 DevOps 关注点高度重叠。

特性 说明
Availability 系统需要保持可用的时间长度;例如,如果需要 24/7 可用,则需要采取措施确保系统始终可用。它指的是软件可操作和可访问的程度。
Continuity 灾难恢复能力。
Performance 衡量应用程序请求和响应周期所需的时间。它包括压力测试、高峰分析、功能使用频率分析、所需容量和响应时间。它也可以是更具体的度量,例如首屏渲染时间,即网页首次可见的时间。
Recoverability 业务连续性要求(例如,发生灾难时,系统需要多快才能重新上线?)这将影响备份策略和对复制硬件的要求。它也指软件从故障中恢复的能力,通过恢复任何受影响的数据并重新建立系统的所需状态。
Reliability/Safety 评估系统是否需要具备故障安全能力,或者其任务关键性是否影响生命。如果系统发生故障,是否会给公司带来巨额损失。它指系统在指定条件下和指定时间内运行的程度。
Robustness 在互联网连接中断、断电或硬件故障时,处理错误和边界条件的能力。
Scalability 系统随着用户或请求数量的增加而执行和运行的能力。这意味着处理大量并发用户而不会出现严重的性能下降。

结构特性

结构性架构特性关注代码结构。在许多情况下,架构师对代码质量问题负有独立或共同的责任,例如良好的模块化、组件间的受控耦合、可读性强的代码以及其他内部质量评估。

特性 说明
Configurability 最终用户通过可用界面轻松更改软件配置方面的能力。
Extensibility 系统的可扩展性。
Installability 系统在所有必要平台上安装的便捷性。它指软件在指定环境中安装和/或卸载的程度。
Leverageability/Reuse 跨多个产品利用通用组件的能力。它指开发人员在多个系统或构建其他资产中重复使用资产的程度。
Maintainability 开发人员修改、纠正或使其适应环境和/或需求变化的有效性和效率程度。
Portability 系统是否需要在多个平台上运行。它指开发人员将系统、产品或组件从一个硬件、软件或其他操作或使用环境转移到另一个环境的程度。
Supportability 应用程序所需的技术支持级别。系统中调试错误所需的日志记录及其他设施的级别。
Upgradeability 从该应用程序/解决方案的旧版本轻松/快速升级到新版本的能力。

交叉特性

交叉架构特性指的是那些难以归类或超出传统类别,但却形成重要设计约束和考虑的特性。

特性 说明
Accessibility 确保所有用户(包括色盲或听力障碍等残障用户)能够访问系统。它指使软件可供具有最广泛特征和能力的人使用。
Archivability 数据是否需要在一段时间后归档或删除。
Authentication 确保用户是其所声称的身份的安全要求。
Authorization 确保用户只能访问应用程序内特定功能(按用例、子系统、网页、业务规则、字段级别等)的安全要求。
Legal 系统在哪些法律约束下运行(数据保护、萨班斯-奥克斯利法案、GDPR等)?公司需要哪些保留权利?关于应用程序构建或部署方式的任何规定。
Privacy 隐藏内部公司员工交易信息的能力(加密交易,甚至数据库管理员和网络架构师都无法查看)。
Security 数据是否需要在数据库中加密?内部系统之间网络通信是否需要加密?远程用户访问需要何种类型的认证?它指软件保护信息和数据的程度,以便人员或其他产品或系统具有与其授权类型和级别相称的数据访问程度。
Supportability 应用程序所需的技术支持级别。系统中调试错误所需的日志记录及其他设施的级别。
Usability/Achievability 用户使用应用程序/解决方案实现目标所需的培训水平。它指用户可以有效、高效、满意地使用系统达到预期目的。

可用性 vs 性能

在架构特性中,没有绝对的"更重要"之分,只有权衡取舍 (trade-offs)。这是软件架构的第一定律。架构师很少能够设计一个系统来最大化每一个架构特征。

可用性和性能之间的选择取决于具体的业务驱动因素、环境和一系列其他因素。例如:

  • 业务需求
    • 如果一个系统对用户来说必须始终可用,即使偶尔慢一点也可以接受,那么可用性可能是更高的优先级。例如,一个紧急服务系统或金融交易系统,即使延迟增加,也必须确保服务不中断。
    • 如果业务目标是提供极快的响应时间,即使偶尔停机也能接受,那么性能可能更重要。例如,高频交易系统,毫秒级的延迟都可能导致巨大损失。
  • 相互影响与权衡:提升某一个架构特性往往会对其他特性产生负面影响。例如,为了提高安全性,可能需要进行更多的加密和间接操作,这几乎肯定会负面影响性能。
  • 上下文决定:不同的系统部分可能需要不同的优先级。例如,在一个在线拍卖系统中,拍卖师界面的可用性和可靠性可能比单个竞拍者界面的可用性更关键。

因此,架构师的工作是分析这些权衡,并根据特定情况选择"最不差的架构"(least worst architecture)。这要求架构师深入理解业务领域,并与所有相关利益方(包括开发人员、业务分析师、产品负责人等)进行协作,而不是孤立地做出决策。