译者 | 张凯峰
策划 | 丁晓昀
架构决策记录(ADRs)是开发团队对系统所做的架构决策的重要沟通工具。如果缺乏对什么是架构的明确定义,同时也没有其他地方来记录重要决策,ADR 可能会远离其初衷,失去焦点和效果。
ADRs 旨在揭示架构决策,以此来提高透明度和责任性。但当它变得臃肿,并包含团队所做的每一个决策时,它就成为了对立面,因为架构决策淹没在其他被扔进 ADR 的内容中,难以被轻易发现。
为什么需要 ADR?
在之前的文章中,我们观察到在动态软件开发方法中,解决方案会随着时间的推移而演变(例如敏捷开发),软件架构是由一系列关于系统如何处理质量属性需求的决策来定义的。这与以软件架构文档为主要定义的前期架构方法形成了对比。
ADR 使得架构决策变得透明,帮助开发团队澄清正在做什么以及为什么这样做,并为将来支持和增强系统的人保留这种推理过程。
当软件架构通过一系列决策的变化而演进时,这些决策是基于假设和测试这些假设的实验而产生的,开发团队需要一种跟踪他们所做的架构决策的方法。
随着时间的推移,其中一些决策可能会发生变化,开发团队需要一种方便查看这些决策的方式。即使它们没有变化,未来的团队也需要了解所考虑的选择和权衡,以便能够做出更好的系统演进决策。
ADR 的目的是什么?
对于这个问题,没有一个简单的答案。撰写这个主题的作者们认为 ADR 应该记录重要的决策,并且有些人甚至进一步说应该是架构上的重要决策。这听起来是合理的,但是很难就重要性达成一致,而且更难决定什么是架构上的。
许多团队由于没有地方记录任何重要决策,将他们认为重要的任何决策都放入 ADR 中,这就淡化了架构方面,使 ADR 变成了一个"任意决策记录"。这样做会使 ADR 负载过重,有很多不应该存在的决策,而这些决策的存在只会让真正重要的架构决策更难以看到。所以,要决定将什么放入 ADR 中,我们必须决定什么是架构的?这并不像看起来那么容易。
"架构的"是什么意思?
最近,我们陷入了一个《公主新娘》的剧情里,伊尼戈·蒙托亚(由曼迪·派廷金饰演)对维兹尼(由华莱士·肖恩饰演)说:“你总是用那个词……我觉得你并不明白它的意思。”
我们在软件领域经常提到“架构”这个词,好像我们完全知道它的意义。但是当我们更仔细地审视这个概念时,我们很难准确地界定它的含义。在本文中,我们来尝试更明确地定义我们认为的架构和非架构,并为做出决策提供更明确的标准。
“架构”这个术语在软件开发中的应用实际上是问题的一部分;它是错误的隐喻。在物理世界中,架构主要关注可用性和美学。我们所谓的“软件架构”更类似于结构工程,主要关注物理系统如何弹性地承受负载。
同样,软件架构的艺术是预测软件系统的负载并为其设计。一个关键区别是结构工程是基于几千年经验的广泛知识体系,并通过科学推导出的物理定律和数学模型来加强。软件与此完全不同。它是编码的思想,并且除了某些类型的算法之外,解决问题的标准方法很少。
一个理解软件架构的良好起点是 Grady Booch 的观察,它对比了架构和设计:
"所有的架构都是设计,但并非所有设计都是架构。架构代表了塑造系统形式和功能的一系列重要设计决策,而重要性是通过变更成本来衡量的。" (Grady Booch on Twitter)。
这个观察的重要部分是:
如果一个决策不涉及这两个方面的任何一个,我们认为它不应该包含在 ADR 中。让我们更详细地审视这个断言。
什么样的变更是昂贵的?
有些决策是昂贵的变更,但并不一定复杂,复杂指的是“在智力上具有挑战性”或者“如果做出错误决策可能会造成严重后果”。换句话说,重写代码并不复杂,真正复杂的是重新思考代码背后的概念。
举个例子,有些决策是昂贵的变更,但并不复杂,比如:
使用适当的转换工具,这些决策实际上可能并不会很昂贵。以前重写用户界面是昂贵的,但现代 UI 设计工具和框架使这种工作相对廉价。决定使用哪个 UI 框架、SQL 数据库或编程语言是一个实现细节,而不是架构决策。这些都是重要的决策,但它们并未达到架构决策的层面。
甚至"架构上重要"的成本标准归结为"解决方案的形状"。
"解决方案的形状" 是什么意思?
对我们来说,“解决方案的形状”指的是系统用于解决问题的基本数据结构和算法。以上面关于 SQL 数据库的观察为例,选择特定的 SQL 数据库可能在架构上并不重要,但是从使用行和列来表示基本概念转变为使用树结构或非结构化数据是重要的。搜索、排序和更新这些不同类型表示的算法非常不同,具有不同的优势和劣势,因此你的选择将显著影响系统满足 QARs 的能力。
更一般地说,对我们来说,架构决策具有以下特点:
架构首先为系统能够解决的问题类型设定了限制,有时甚至会对开发人员看待不同解决方案的能力造成一种类似锤子 - 钉子的盲目性,使他们无法看到其他可能的选择。改变架构决策意味着改变系统所处理的基本概念以及处理这些概念的方式。
除了表示关键概念的算法和数据结构之外,其他选择也在塑造架构中起着关键作用,例如:
最终,所有这些选择都会转化为不容易更改的代码,因为这些选择的代码影响分散在整个软件中,而不是局部的。如果某个东西可以局部化和封装,通常不是属于架构范畴,因为可以在不对代码产生连锁影响的情况下进行更改。
架构和决策的持久性
有时候,决策的预期寿命会使团队认为该决策是架构性的。大多数决策都会变成长期决策,因为大多数系统的资金模型只考虑了开发的初始成本,而不考虑系统的长期演进。在这种情况下,每个决策都变成了长期决策。然而,这并不意味着这些决策就是架构性的;它们需要具有高成本和复杂性,才能在撤销 / 重做方面具有架构上的重要性。
举个例子,选择数据库管理系统的决策通常被认为是架构性的,因为许多系统将在其整个生命周期中使用它,但如果这个决策可以轻松地被撤销而无需修改整个系统的代码,那么它通常并不具备架构上的重要性。现代关系型数据库管理系统技术非常稳定,不同厂商的产品相对易于互换,因此只要与数据库的接口进行了隔离,就可以比较容易地将商业产品替换为开源产品,反之亦然。架构上的决策是局部化数据库依赖和抽象特定厂商接口,而不是选择数据库本身。
决策的持久性在 ADR 中起作用的地方是解决可持续性和弹性的问题。可持续性涉及系统能够应对未知概率和影响的未来事件集。弹性是指系统在发生这些事件时能够抵抗失败的能力。当人们说某个系统具有可持续性时,他们的意思是相信该系统能够处理他们能够想到的一切,甚至是无法预料的事情。
何时需要做架构决策?
在过去,一个团队会在系统开发的早期创建一个软件架构文档,该文档将指导系统在整个生命周期中的开发。
当一个团队使用敏捷方法来开发系统时,决策记录(ADRs)将集体取代软件架构文档,因为它们逐步记录架构以支持系统的逐步开发。我们在之前的文章中已经描述了最小可行架构(MVA)如何与最小可行产品(MVP)增量并行演化。实际上,这意味着团队将随着解决方案的演进而逐渐做出架构决策。与软件架构文档不同,ADRs 记录的决策是一次性地预先制定的。
在所有重要决策中 使用 ADRs 有什么坏处?
简而言之,它会使事情变得混乱,使真正的架构问题更难以看清。这样做会使关于基本决策的讨论变得更加困难,因为问题不明确,尤其是如果决策的影响没有完全说明。
出于多种原因,团队仍然需要记录非架构性的决策,其中许多归结为需要记录决策及其原因,以便以后有人需要解释或证明。有时,为了将决策记录在 ADR 中,决策被分类为“架构性决策”,因为没有更好的地方可以记录它。
ADR 不应该用于以下用途:
结 论
尽管所有的架构决策都很重要,但并不是每个重要的决策都是架构决策。创建架构决策记录和其他重要决策的分离有助于提高组织间的沟通。ADR 中包含了通常不会引起广泛兴趣的技术讨论,将它们分开使系统的架构更易于理解。
如果 ADR 只关注架构,它们可以让人了解团队在权衡选择和取舍时的思考过程的演变。决策从来都不是错的,它们只是团队在某个时间点上思考的表现。是的,随着时间的推移,他们可能会选择不同的方法,但保留这种演变的记录是有用的。了解团队的思维如何演变可以提供对当前和未来权衡的见解。
在软件架构中,往往没有完美的解决方案,只有需要平衡的“不太完美”的替代方案。能够更清楚地看到这些选择有助于当前和未来的团队更好地理解他们可能需要做出的权衡。
原文链接:
https://www.infoq.com/articles/architectural-decision-record-purpose/
声明:本文为 InfoQ 翻译,未经许可禁止转载。