有个关于架构设计的玩笑是,没有什么问题是不能用两个框加一条连线解决的,如果有的话,那就再加一个框和一条连线。
确实架构师们经常用框和连线来表达架构决策是什么。但有时候我们更希望理解这个决策的前因后果,尤其是那些正因为这个历史决策承受痛苦的人。如果我们不理解这个历史决策背后的动机,那么我们只有两个选择:
如果这个决策的上下文没有变化,这个选择可能没有问题。但如果这个决策的上下文已经改变了,可能我们错过了一个调整决策的机会。我很怀疑,如果我们不理解某个决策背后的动机时,是否真得能在实际工作中贯彻这个决策,不会走样。
同样的,如果这个决策的上下文已经失效了,那么绕过它可能没有问题。但另一种可能即我们在无意间把事情搞砸了。
因此,这两个选择都不是好主意。那么我们如何穿越到历史决策制定的时间线去一窥背后的动机呢?还是得靠文档,我们称之为架构决策记录(Architecture Decision Record,简称ADR)。
在网络上,可以找到各种各样的架构决策记录模板,那么架构决策记录应该包含什么呢?既然记录架构决策的动机是为了理解该决策背后的动机(好拗口),那么我们应该将更多的笔墨放在Why & What上。本着精简文档的原则,我认为架构决策记录至少应该包括以下几项:
描述要解决什么问题以及为什么是现在这个时间点来解决这个问题
描述在解决该问题时有什么限制条件,例如预算/时间线/资源
描述在做出决策时带着什么假设,由于各种原因在决策当时,尚无法验证
列举相关的架构决策或架构原则,它们也有助于帮助读者理解决策推导过程
一组备选方案,如果有人总是问“你们有没有考虑过这种方案”,那么这里是回应的好地方。每个备选方案除了方案本身的描述外,还应该说明如果选择了该方案会有什么后果/代价
最终选择了哪个备选方案,其后果/代价是什么
####状态
草稿/待评审/已通过,可以根据你所在组织的架构决策流程来定义
那么什么样的决策适合以架构决策记录的形式来记录呢?这个需要根据你所在组织的情况来定,但原则上太细粒度的设计决策或太宏观的方向决策都不太适合。但不管什么样的决策,其背后的动机都值得记录下来,只是未必以架构决策记录的形式而已。
例如,需要新增一个API或是修改已有的API,那么通过代码的提交备注就能记录了。而引入中台架构则太宏观了,可能需要一个报告来能说清。
原则上,架构决策记录应该尽可能开放,这样才能最长程度避免“有时候我们更关心架构决策背后的动机”中出现的闷头干的情况。所以不管是直接放到Wiki上,或是放在共享文件夹里,都需要将如何在避免泄密(如果有的话)的前提下,最大化读者可见性作为考量之一。
另外,应该考虑将架构决策记录纳入配置管理(指保存历史版本),某些Wiki(例如Confluence自带历史版本功能),或者采用普通文档(是类似于Markdown的普通格式,而不是二进制的Word文档,以便更方便的观测修订历史)搭配源码工具(Git/SVN等)。
下面我将用一个虚拟的例子来演示一个架构决策记录,我不会做说明,请帮我验证一下这个说明能否达到它应有的作用。
我们是一家依赖经销商分销的企业,现在正在尝试将指定商品直接向消费者销售(详见 关于B2C试点业务 ),这要求我们为之建立在线收款的能力。
时间约束:B2C试点项目预计于20年9年上线运行,期间大约有2周的时间完成与 在线支付供应商 的集成。
业务约束:需要保障财务对账工作可以某种方式进行。考虑到 B2C试点业务 的计划,对账工作未必需要以自动的方式执行。
根据 ADR-32-引入在线支付供应商 ,为尽可能以最小的代价,支持多种支付方式,我们会与一家 在线支付供应商 合作,但商务协商仍在进行中。
从长远来看,O2是更好的选择,但我们目前需要在没有足够的工程师的情况下满足非常有挑战的项目时间线。因此建议先采用O1,在需要引入订单二次收款能力时切换到O2。
####状态
待评审