
关键要点
架构实验专注于测试架构决策。一个决策如果回退代价越高,就越需要通过实验进行验证。
并非所有架构决策都需要实验。对于回退成本较低的决策,实验的投入可能得不偿失。
实验不仅仅是“玩弄技术”。在学习新技术时,“玩弄”可能很有价值,但这不等同于架构实验。
实验应有明确的范围和时间框架。如果实验无限期进行,说明其定义不清晰。
实验结果应能明确指出某项决策是否可行,是否需要重新审视。如果不能达成这一目标,说明实验设计不够具体,需要重新设计。
在以往的文章中,包括《软件架构与实验的艺术》(Software Architecture and the Art of Experimentation)和《如果架构实验这么好,你为什么不做?》(If Architectural Experimentation Is So Great, Why Aren’t You Doing It?),我们探讨了为什么认为架构实验是评估架构决策的重要工具。最重要的原因,是为了降低因错误架构决策而导致系统成本灾难性增长的风险与可能性。
例如,MVP 是关于商业价值的实验,也就是验证客户是否认为某个潜在解决方案有价值;而 MVA 则是关于该 MVP 是否能够被长期、可持续地交付与支持的实验。
从某种意义上说,我们一直在进行实验,但大多数情况下是无意的。有意的实验意味着我们清楚地知道自己正在进行实验,并为其设定了明确的目标和边界,从而提高我们从实践中学习的能力。而意外的实验则较为随机,通常只有在事情“脱轨”之后我们才会意识到那其实是一次实验。
为了使内容更具体而不流于规定性,本文将探讨关于架构实验中最常被提及的一些问题。
哪些决策需要通过实验验证?
简而言之,需要实验的是那些一旦出错将付出高昂代价的决策,尤其是在出错可能性较高的情况下。按照某种总体影响的衡量标准(例如:出错的概率乘以出错的代价)对各项决策进行排序,有助于确定应优先验证哪些内容。
决定是否需要开展实验的难点在于克服认知偏差,并识别出哪些决策带来了最大的风险。当对某项决策提出质疑时,应审视其背后的基本假设,并问自己:“我们是如何知道这是真的?”如果发现该决策主要依赖于主观判断而非事实依据,那么进行一次实验以验证其有效性可能是值得的。
那些让人感到不放心的决策,通常是进行实验的良好候选。这一点在面对“专家意见”时尤为适用。有时,团队对某项挑战并不熟悉,只有其中一位成员例外,被视为该领域的“专家”。这位“专家”可能是对的,如果确实如此,那当然最好;但团队的其他成员要真正确信,还需要的不仅仅是“相信我”这样的话。
每个人都有盲点,即使是“专家”也不例外,而实验将帮助团队拓展技术知识和经验。透明度至关重要——少数占主导地位的团队成员可能会坚持自己的观点,强迫做出让其他成员感到不放心的决策。其他团队成员需要有表达自己担忧的途径。如果任何团队成员对某项架构决策感到不放心或不确定,实验将有助于解决他们的疑虑或不适感,同时也能为较为沉默的声音提供发声的机会。
有些决策虽然修改代价高昂,但并不一定复杂。我们所说的“复杂”,是指“在智力上具有挑战性”,或者“一旦决策错误,可能会把事情彻底搞砸”。换句话说,重写代码本身并不复杂——真正的复杂性在于重新思考代码背后的理念。架构决策始终伴随着复杂的权衡。
哪些决策通常值得仔细审视?
通常值得深入考量的决策包括:
系统所采用的基本概念及关键抽象的决策,这些通常体现在用于在整个系统内部乃至系统之间共享信息的数据结构中(例如类、类型等)。
关于如何使用这些数据结构的决策,即用于访问和操作这些数据结构的基本算法。
除了代表关键概念的算法和数据结构之外,其他一些选择也在架构的构建中发挥着关键作用,其中包括与以下方面相关的决策:
信息传递范式的变更 —— 如从同步切换为异步
响应时间承诺的变更 —— 如从非实时转为实时
并发与一致性策略的变更 —— 例如乐观锁与悲观锁之间的选择
事务控制算法的变更 —— 如失败/重试策略
影响延迟的数据分布方式的变更
缓存一致性策略的变更,尤其是针对联合数据的情况
安全模型的变更,特别是当安全访问粒度细化至单个对象或元素时
这类决策涉及组件之间的知识共享,《软件设计中的耦合平衡:构建模块化软件系统的通用设计原则》(Balancing Coupling in Software Design: Universal Design Principles for Architecting Modular Software Systems)一书的作者 Vlad Khononov 将其称为“集成强度”(integration strength)。两个组件之间共享的知识越多,集成强度越大,耦合度也越高。因此,实验可以帮助团队优化系统中的组件耦合。
即使某项决策涉及使用成熟且广为人知的技术,如果该技术将被以新颖的方式使用,仍可能需要进行实验。例如,组织的架构标准可能要求使用传统的 SQL 数据库;但如果团队需要以非典型的方式使用该产品,例如处理非结构化数据,则应通过实验验证这种新颖用法是否能够满足其架构目标。如果不能,他们可以寻找其他替代方案;更重要的是,他们将拥有偏离既定标准的有力证据。
最后,引入新技术的决策应经过实验验证。例如,如果一个团队希望在 MVA 中使用事件存储数据库,而该产品并不在已批准的软件列表中,那么实验可以评估是否值得为采用该新技术投入精力。
什么时候不该做实验?
当推翻一项决策的成本较低或微不足道时,进行实验并不会显著降低成本,反而可能增加成本。通常,团队成员以往在类似系统或技术挑战中的经验会指导他们判断决策的可逆性。
此外,有些决策虽然更改成本很高,但并不复杂,例如:
重新设计应用程序的用户界面。即使使用了 UI 框架,改变视觉隐喻也可能耗时且代价高昂,但只要不影响系统所处理的基本概念,这类更改通常不会很复杂。
将一个主要组件或子系统替换为功能相当的另一个组件或子系统。例如,将一个供应商的 SQL 数据库替换为另一供应商的 SQL 数据库。此类更改虽然需要投入一定工作量,但转换工具和避免使用专有功能可以提供帮助。只要新组件/子系统支持与旧组件/子系统相同的基本概念,系统架构就不会因此改变。
只要编程语言支持相同的抽象和编程语言概念,改变编程语言甚至可能不会对系统架构产生重大影响。换句话说,语法的变化并不具有架构意义,但基本概念或隐喻的变化则具有架构意义。例如,从面向对象语言转向函数式语言,就需要进行实验。
如果有合适的转换工具,推翻这类决策的成本可能并不高。过去,重写用户界面代价昂贵,但现代 UI 设计工具和框架已使这类工作相对廉价。选择使用哪种 UI 框架、SQL 数据库或编程语言属于实现细节,而非架构决策。虽然这些都是重要决策,但尚未达到架构决策的层级。
对实验的常见误解
实验不仅仅是玩弄技术。以非结构化、探索性的方式尝试新想法和新技术确实有其价值,人们在这样做时常称之为“实验”。而我们所说的实验,是指一个有明确流程的过程:首先形成假设,然后构建某种方案来验证该假设,最终接受或否定它。我们更倾向于将另一种方式称为“非结构化探索性学习”,这类活动包括黑客马拉松、“10% 时间”以及其他职业发展机会。
例如,想要学习如何使用生成式人工智能,随意尝试可能是必要的,但只有当你测试某个大型语言模型(LLM),以验证它是否满足特定需求并支持 MVP 的交付时,这才算是一项真正的实验。
你需要哪些信息才能开始工作?
正如上一节所述,实验是一个严谨的过程,包含形成假设并构建方案来验证该假设,最终接受或否定它。要开始实验,你需要以下信息:
你想要测试的决策——可能是因为有人“感觉不妥”。
实验的精确时间框架,包括计划开始时间和持续时长。
限定实验范围的明确假设。
预期结果(假设),用于与实际结果对比,从而判断实验成功或失败。需注意避免将实验结果超出其适用范围进行推断。
团队对实验目标和范围达成共识,使团队明确何时实验成功,何时偏离方向。
什么时候该 “终止 ”实验?
如果实验似乎永远不会结束,比如团队觉得“只需要再多一点时间”才能看到结果,这通常表明实验已经失去焦点。实验应当有明确的时间范围和目标。当发现实验未能在预定时间内取得预期成果时,就应该果断终止,并设计新的实验方案来验证假设,争取获得更明确的结论。即使是“失败”的实验,也能提供有价值的信息,比如表明假设难以验证,或者为后续更清晰的实验提供借鉴和指导。
如何处理实验结果?
实验有三种可能的结果:
实验失败,意味着需要重新审视该决策。你需要回头重新考虑该决策及其可能的替代方案。在最坏情况下,可能需要放弃 MVA(甚至可能包括 MVP),重新开始。
实验成功,表明该决策得到确认,你可以继续推进其他决策。
实验结果不确定,这种情况下可能需要重新设计实验,以验证决策的正确性。重新设计非常重要,应将其视为一次全新的实验,而非原实验的延续。
结论
实验帮助团队验证架构决策,能够降低系统成本,减少因推翻错误决策所带来的浪费。因此,并非所有架构决策都需要实验,只有那些推翻成本极高的决策才值得进行实验;其他变更可能不值得承担实验的成本。
实验不仅仅是玩弄技术。团队成员常用“实验”一词来描述学习和探索新技术的重要过程,而真正的实验则有所不同,它专注于验证决策。
实验结果应当表明某项决策是可接受的,还是需要重新审视。如果无法得出明确结论,说明实验设计不够具体,需要重新设计。
作者简介:
Pierre Pureur 是资深软件架构师,拥有丰富的创新与应用开发经验,深耕金融服务行业,具备广泛的咨询背景和全面的技术基础设施知识。曾任某大型金融服务公司的首席企业架构师,领导大型架构团队,管理大规模并发应用开发项目,推动创新计划,制定战略与业务方案。他是《Continuous Architecture in Practice: Scalable Software Architecture in the Age of Agility and DevOps》(2021)和《Continuous Architecture: Sustainable Architecture in an Agile and Cloud-Centric World》(2015)两书的合著者,发表多篇相关文章,并在多场软件架构会议上发表演讲。
Kurt Bittner 拥有超过 30 年在短周期、反馈驱动环境中交付软件的丰富经验。他帮助过多种行业组织实施敏捷软件交付实践,涵盖大型银行、保险、制造、零售及政府机构等。他曾在 Oracle、HP、IBM 和微软等大型软件交付组织工作或合作。作为前 Forrester Research 技术行业分析师,Kurt 广泛撰写敏捷团队协作与领导力相关的文章。
原文链接:
https://www.infoq.com/articles/architectural-experimentation-faq/
评论