- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
作者:倪新明 。
ADR 是一种性价比非常高的 架构决策文档化实践 ,团队引入和实践成本很低,却能为团队带来极大收益! 。
不论是在传统的IT行业,还是互联网行业,研发团队在架构决策层面或多或少的都会 面临以下问题或挑战 :
•新成员加入团队,对系统现有的架构决策可能会 盲目遵守 ,只知其然,不知其所以然;或者 挑战或违反 约束,持续挑战当前决策,“质疑”决策的合理性和正确性,负责人需要不间断的解释、同步、推动达成共识 。
•架构决策的潜在问题随着时间推移暴露,但, 如果决策时进行充分分析这些问题可能会提前发现和规避 。
•现有系统架构决策是 如何演进 ?当前决策背后的 动机是什么 ?有可能团队内已经没有人能准确的回答 。
•相似架构决策场景在系统中 重复出现 ,由于遗忘决策原因,或团队成员变化等因素,仍要花时间去分析、设计和推动干系人达成共识 。
•团队内 只有少部分人负责架构设计 ,其他团队成员无机会参与,但实际上 团队成员有相应诉求 ,至少能够了解某项关键架构设计的决策过程 。
•即使团队内部接手的项目, 你能快速获取系统关键架构决策及其原因吗 ?你可能会从代码库中寻找架构决策的蛛丝马迹,但很难获取架构决策背后的动机以及决策的演进过程 。
基于以上这些问题,我们想 :
•通过 最小但依然高效 的方式记录系统的架构决策 。
•能够 识别系统关键决策的演进过程 。
•架构决策以及设计最佳实践能够在团队间 高效同步 。
•团队成员都有机会参与到架构设计决策过程中 。
通过文档形式记录架构决策首当其冲的问题是: 文档过期 !! 。
确实,过期问题是文档化必然面临的问题 。无论通过什么机制,比如强流程、自动化更新等都存在过期风险。那为什么还要选择记录架构决策呢?基于以下两个原因:
• 性价比 :架构决策文档化的收益远大于维护过期带来的成本 。
• 轻量级 :保持ADR的简短、轻量, 规模越小的文档越容易保持与实际的同步 .
Architecture Decision Record ,缩写ADR,即架构决策记录,该实践最先由Michael Nygard发起,是记录架构决策最有效的方式之一。简单来说,ADR是一种对架构决策的文档化记录,其 目的是通过文档化的形式记录系统的架构决策、原因以及决策过程 .
通过对系统架构决策进行有效记录,团队可以从以下几个层面获得收益:
•新人引导,便于快速熟悉系统新的团队成员可以快速获取系统的历史架构决策,理解决策背后的背景、决策过程以及相关影响 。
•项目交接,对已有决策进行文档化积累敏捷环境强调团队对知识的快速学习,基于ADRs团队可以快速熟悉已有系统的架构演进过程 。
•对齐认知通过推动落地ADRs,团队成员更容易对设计最佳实践达成一致认识和理解,进一步避免后续建设过程中的“重复造轮子”,提升设计知识在团队间复用 。
建议 的ADR的基本结构包括 标题、状态、背景、决策、影响 共五个部分,一般情况下,推荐增加 一致性和备注 两个极具价值的额外章节作为补充.
需要说明的是, 团队可以按需增加其他章节以增强ADR的表现能力 ,比如增加可选方案章节对可选方案进行详细描述.
标题【必选】 。
ADR的 “标题” 部分主要包括两部分,其一是顺序编号,其二是对架构决策的简短描述。标题的描述需要确保对架构决策进行准确描述、清晰无歧义,同时,也要 保持简短明了 .
例如:ADR 01. 订单服务和履约服务之间采用异步消息机制 。
状态【必选】 。
ADR的 "状态" 限定为 待审核 , 审核通过,被取代 三种状态之一.
•待审核:决策必须被高级别决策者或ARB审核 。
•审核通过:架构决策已经被审核,并已准备就绪进行实现 。
•被取代:架构决策已发生变更,并被另一个ADR取代。该状态表明,之前的ADR一定是被审核通过的,处于提议状态未审核通过的ADR是不允许流向该状态。处于提议状态的ADR只能持续修改直到审核通过。 被取代状态提供了一种有效的架构决策追溯机制,能够帮助团队识别架构决策的演进过程 .
背景【必选】 。
推动架构师对此项 架构决策的具体背景或问题进行描述,以及简洁扼要地表述可能的可选方案 。决策背景在一定程度上也是对系统架构的一种描述.
说明: 不建议 在此章节进行详细的替代方案分析和说明,如果确实需要进行详细阐述,则建议增加额外的章节进行说明.
可选方案【可选】 。
对可选的替代方案进行详细描述,对比不同方案的优劣势 。
决策【必选】 。
该部分包含了 具体的架构决策以及相应的决策依据 ,原则上要使用肯定式、命令式的描述方式表述具体的架构决策,不要存在主观的、消极的、模棱两可的、可能存在歧义的措辞。说明:关注Why 而非 How,理解架构决策的原因比理解怎么实现更加重要 。
影响【必选】 。
该部分描述此项架构决策的整体影响。 每项决策都会或多或少的对现有系统产生影响,包括好的影响和坏的影响 ,通过该章节推动架构师思考这些影响 是否超过架构决策的收益 .
一致性【可选】 。
该部分并不是标准ADR元素,但同样颇具价值, 其作用在于推动架构师从架构一致性的视角思考所作架构决策如何进行度量和治理 。 架构师必须确定该项架构决策的一致性保证是通过人工方式还是通过自动化方式实现 。如果可以通过自动化方式进行,则在该章节明确说明自动化的执行方案.
备注【必选】 。
备注部分并不是标准ADR的结构,但是强烈推荐增加该章节。备注部分主要包含的ADR的各种元数据,例如:
原作者、审核日期、审核人、替代日期、最后修改日期、修改人、最后修改内容 。
说明:有些团队认为备注部分的元数据信息没有太大价值,特别是,当团队将ADRs与代码一同存储在配置库时(并不推荐该种存储方式)。但实际上, 将元信息作为ADR的一部分比依赖配置库更具价值和优势 .
ADR文档具体存放在什么位置,比如FTP服务器、WIKI或者同项目代码配置库,不同的团队可以根据情况进行灵活选择。原则:ADR能够被干系人便捷地获取.
方式一:基于类似Git的配置库存储 。
优点:
•架构决策离代码很近,方便研发人员获取 。
•通过配置库的版本管理能力轻松的实现ADR的变更管理 。
缺点:
ADR的干系人不仅仅是研发人员,还有技术经理、产品经理、业务人员等其他角色的项目干系人。基于太技术性的配置库进行存储,显然对除研发以外的角色不太友好。同时,还需要对非研发人员开通仓库权限,代码安全性也是须要考虑的因素。另外,基于配置库存储不太方便存放同一系统不同应用下通用的架构决策以及应用间的集成架构决策.
方式二:类似WIKI的在线协同编辑共享系统内 。
优点:干系人友好在线协作方便处理跨应用的架构决策 。
缺点:开发人员不友好,离开发库较远 。
基于对跨应用架构决策的存储,团队选择将ADR存储在在线协同文档平台,并通过合理的文件夹结构进行组织,参考以下组织形式:
如果要落地ADR,则须要将其融入到现有的研发过程中。ADR涵盖的流程活动主要是:
制定ADR 。
•活动名称:制定架构决策记录(ADRs) 。
•前置要求:无 。
•干系人职责: 子系统负责人负责制定子系统作用域内的ADR,系统架构师负责跨系统架构决策制定 。
•活动输入:PRD活动输出:《架构决策记录》 。
•执行形式:线下,或非正式的头脑风暴 。
•执行时间:属于系统设计的一个子活动,在系统设计阶段进行 。
评审ADR 。
•活动名称:评审ADR 。
•活动目的:评审ADR的完整性和正确性,确保架构决策的合理性 。
•前置要求:已完成ADR制定 。
•干系人职责:ADR指定人发起评审,系统架构师及核心研发参与评审活动 。
•活动输入:ADRs 。
•活动输出:ADR评审记录(在ADR文档上更新评审信息) 。
•执行形式:正式或非正式的评审会 。
•执行时间:技术方案内部评审时,对该方案相关的ADR进行评审 。
问题一:写ADR的 “时间成本较高” ,延长了技术方案设计周期 ?
答: 否! 。
该疑问可能主要来自于以下几个原因:
•写文档 = 费时间?大多数研发人员排斥文档,且没有写文档的习惯.
•对ADR模板理解不够深入和准确,撰写过程中无从下手 。
•决策缺少必要的分析习惯,对架构决策缺少必要的对比、分析,在撰写ADR时,缺少必要的依据,不得不额外查找资料,所以写的“很慢” 。
但实际上,如果作为架构决策者具备决策分析的习惯,特别是在技术方案设计时,进行过充分的决策分析, 1-2页的ADR文档撰写不会超过 1 个小时,甚至在半个小时内完成 。即使制定和评审ADR影响了一小部分设计时间,通过对关键决策的充分分析和审重决策所带来的价值远胜过返工造成额外成本 。
问题二:遗留系统没有必要再写ADR ?
答: 否! 。
价值是决定是否写ADR的因素之一 ,切忌ADR只对当前架构决策进行记录。对于遗留系统,在团队遗忘之前,记录其关键架构决策依然具有较大价值.
问题三:ADR这种文档化机制与敏捷冲突 ?
答: 否! 。
敏捷宣言中指出:可以工作的软件胜过面面俱到的文档。其强调左侧更有价值,但不否定右侧的价值.
因此, 文档化并不一定与敏捷理念发生冲突 。 通过采用轻量级的文档机制,记录具有核心价值的东西,确保文档机制不会成为团队负担,本身与敏捷文化相互契合 .
问题四:ADR评审是不是流程太重 ?
答: 可能,但是有必要! 。
ADR评审是引入ADR机制的重要活动之一,不可忽略! 正是通过多干系人参与下的评审活动,才能产生ADR的诸多重要价值 。通过这种正式或非正式的评审活动:
•提升架构决策的合理性和正确性 。
•提升团队的技术氛围 。
•提升团队成员的技术思考能力、技术水平、架构决策的参与感,实现架构决策在团队成员间的高效同步...... 。
因此,ADR的评审活动是必要的,从效率考虑,团队可以优化评审过程.
问题五:ADR模板很多,团队应该如何选择?
答: 没有标准的,只有最适合的 ! 。
ADR没有统一的模板,选择适合团队的,建议:
模板保持轻量,不要试图覆盖所有的场景,否则,ADR会成为团队成员的负担 。
更重要的是,ADR模板和模板元素的含义一定要在团队成员间达成一致 。
问题六:什么时候需要写ADR没有量化条件,所以很难落地?
答: 否! 。
原则上:对系统产生显著影响的架构决策需要写ADR.
如何定义 "显著影响" 没有量化指标,但如果存在以下场景可能是需要写ADR的信号:
•直接影响高优先级的架构属性 。
•修改对外接口:对外提供的接口修改往往需要进行充分影响分析 。
•引入或者移除依赖:依赖的加入和移除往往标示着组件能力的引进和废弃 。
•改变系统的通用结构:工程结构是应用架构的重要维度之一 。
•迫使研发人员改变开发方式接受战略性技术债:重构影响较大的技术债往往对现有系统会有较大影响 。
以上场景只是可能需要写ADR的一些信号,但并不是强制约定.
是否需要写ADR的终极实践准则是:具体情况,具体分析 。
ADR的结构虽然非常简单,但团队在开始实践过程时对于每个章节的内容表述极易出现偏差,在撰写ADR文档时常见的问题如下:
【背景】部分 。
典型反例:
未直接说明推动进行决策的原因:正确的方式是要明确说明进行此次架构决策的背景或动机是什么,明确 WHY对可选方案进行详细说明:ADR实践初期,团队常犯的错误式在 “背景” 部分对方案进行详细的大篇幅论述 。
【决策】部分 。
典型反例:
缺少决策依据说明:决策依据过于简单,不充分,不能推到选择当前决策的论据决策结果表述措辞不够明确、模棱两可 。
【可选方案】部分 。
典型反例:分析角度存在明显倾向性,不够客观 。
【一致性】部分 。
该章节的目的是 推动架构师对如何确保决策被团队遵守进行深入思考,特别是考虑是否可以通过自动化方式进行 。典型的反例词汇是:系统落地、开发实现...... 。
如果不能不同自动化方式进行检查,可能 设计评审、同行代码评审、专家代码评审是可能的方式如果可以通过自动化方式进行,则要说明如何进行自动化方式进行约束校验。例如,如果工程实践通过Archunit进行单测,则可以表述基于Archunit的规则代码.
ADR不仅仅是一份文档,团队将获得以下收益:
•系统关键决策知识留存有助于新团队成员快速融入,知其然也知其所以然 。
•提升团队技术氛围提升团队技术思考力和技术能力,同步最佳实践 。
•提升架构决策的 合理性和正确性 。
•管理技术债的能力 。
•更高效的 架构决策沟通机制 。
•减少重复性的决策讨论和分析 。
•架构决策一致性 推动系统架构约束自动化检查 。
开始 团队的ADR之旅吧! 。
最后此篇关于轻量级的架构决策记录机制的文章就讲到这里了,如果你想了解更多关于轻量级的架构决策记录机制的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个网站。 必须登录才能看到里面的内容。 但是,我使用此代码登录。 doc = Jsoup.connect("http://46.137.207.181/Account/Login.aspx")
我正在尝试为我的域创建一个 SPF 记录并使我的邮件服务器能够对其进行评估。我在邮件服务器上使用 Postfix 并使用 policyd-spf (Python) 来评估记录。目前,我通过我的私有(p
我需要为负载平衡的 AWS 站点 mywebsite.com 添加 CName 记录。记录应该是: @ CNAME mywebsite.us-east-1.elb.amazon
我目前正在开发一个相当大的多层应用程序,该应用程序将部署在海外。虽然我希望它在解聚后不会折叠或爆炸,但我不能 100% 确定这一点。因此,如果我知道我可以请求日志文件,以准确找出问题所在以及原因,那就
我使用以下命令从我的网络摄像头录制音频和视频 gst-launch-0.10 v4l2src ! video/x-raw-yuv,width=640,height=480,framerate=30/1
我刚刚开始使用 ffmpeg 将视频分割成图像。我想知道是否可以将控制台输出信息保存到日志文件中。我试过“-v 10”参数,也试过“-loglevel”参数。我在另一个 SO 帖子上看到使用 ffmp
我想针对两个日期查询我的表并检索其中的记录。 我这样声明我的变量; DECLARE @StartDate datetime; DECLARE @EndDate datetime; 并像这样设置我的变量
在 javascript 中,我可以使用简单的 for 循环访问对象的每个属性,如下所示 var myObj = {x:1, y:2}; var i, sum=0; for(i in myObj) s
最近加入了一个需要处理大量代码的项目,我想开始记录和可视化调用图的一些流程,让我更好地理解一切是如何组合在一起的。这是我希望在我的理想工具中看到的: 每个节点都是一个函数/方法 如果一个函数可以调用另
如何使用反射在F#中创建记录类型?谢谢 最佳答案 您可以使用 FSharpValue.MakeRecord [MSDN]创建一个记录实例,但是我认为F#中没有任何定义记录类型的东西。但是,记录会编译为
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 3年前关闭。 Improve thi
我是 Sequelize 的新手并且遇到了一些语法问题。我制作了以下模型: // User sequelize.define('user', { name: { type: DataTyp
${student.name} Notify 这是我的output.jsp。请注意,我已经放置了一个链接“Notify”以将其转发到 display.jsp 上。但我不确定如何将 Stud
例如,这是我要做的查询: server:"xxx.xxx.com" AND request_url:"/xxx/xxx/xxx" AND http_X_Forwarded_Proto:(https O
我一直在开发大量 Java、PHP 和 Python。所有这些都提供了很棒的日志记录包(分别是 Log4J、Log 或logging)。这在调试应用程序时有很大帮助。特别是当应用程序 headless
在我的Grails应用程序中,我异步运行一些批处理过程,并希望该过程记录各种状态消息,以便管理员以后可以检查它们。 我考虑过将log4j JDBC附加程序用作最简单的解决方案,但是据我所知,它不使用D
我想将进入 MQ 队列的消息记录到数据库/文件或其他日志队列,并且我无法修改现有代码。是否有任何方法可以实现某种类似于 HTTP 嗅探器的消息记录实用程序?或者也许 MQ 有一些内置的功能来记录消息?
如果我有一条包含通用字段的记录,在更改通用字段时是否有任何方法可以模仿方便的 with 语法? 即如果我有 type User = // 'photo can be Bitmap or Url {
假设我有一个名为 Car 的自定义对象。其中的所有字段都是私有(private)的。 public class Car { private String mName; private
当记录具有特定字段时,我需要返回 true 的函数,反之亦然。示例: -record(robot, {name, type=industrial, ho
我是一名优秀的程序员,十分优秀!