查看原文
其他

不要再高估软件架构模式了!

AI前线小组 AI前线 2020-01-17
作者 | Gergely Orosz
译者 | 核子可乐 编辑 | Natalie AI 前线导读: 软件架构最佳实践、企业架构模式以及系统描述的正式方法都是非常重要且实用的工具,总会有合适的场景让它们发挥作用。但在设计系统时,请从简单始、以简单终,尽可能避免一切会无谓提高复杂度的架构与正式工具。

更多优质内容请关注微信公众号“AI 前线”(ID:ai-front)

本文最初发布于 Gergely Orosz 的个人博客,经原作者授权由 InfoQ 中文站翻译并分享。

我个人在大型系统的设计与构建方面拥有比较丰富的实践经验。我参与重写了 Uber 的 分布式支付系统,设计并交付了 Skype on Xbox One,开源了 Uber 的移动架构框架 RIBs。所有这些系统都曾经经历充分设计、多次迭代,并进行过大量白板规划与实际讨论。此后,这些设计思路被整理成一份设计文件,且在实际着手开发之前进行反复传阅以尽量收集反馈意见。

这些系统都有一个共同的特点,就是规模庞大:成百上千的开发人员共同进行构建,它们同时也为数百万人使用的其它系统提供支持。另外,这些系统也并不是全新项目——重写的支付系统负责取代现有的两套支付系统,而且要求不能对正在使用这两套系统的其它数十套系统及团队造成任何业务影响。我们还对 Uber 的 App 进行了重写,其中同样涉及几百名工程师的协作,大家携手将现有功能移植到新的架构当中。

这里,我先聊聊一些可能与大家印象中不同的情况。

第一,这些设计工作没有使用任何标准软件架构规划工具。 是的,我们没有使用 UML、4+1 模型、ADR、C4 或者是依赖关系图。我们整理出了大量图表,但这些图表并未遵循任何严格的规则。这些只是非常简单的图框加箭头的组合,用于描述信息流或者类结构与各组件之间的关系。事实上,同一设计文档中的两份图表经常采用完全不同的 Layout,而且往往由不同的工程师负责添加与修改。

第二,设计工作并不归属于团队中的任何特定架构师。 我们压根没有设置 IT 架构师或者企业架构师职位。大家没有听错,Uber 以及微软 /Skype 都没有专门指定软件架构师角色,即使是主管工程师这类高级技术人员也得定期编写代码。在全部项目当中,我们都引入了经验丰富的工程师,但架构或者设计本身并不归属于任何一位成员。他们为设计过程提供了巨大的帮助,但同时团队中的初级成员也发挥着重要作用,而且可以随时提出反对意见并提供其它替代性方案。

第三,我们几乎没有参考任何常见的架构模式以及软件架构文献中的术语——例如 Martin Fowler 的架构指南。我们根本不提微服务、无服务器架构、应用程序边界、事件驱动架构这类概念。虽然在头脑风暴期间偶尔会涉及,但我们觉得没必要把它们写进设计文档当中。

技术企业与初创企业中的软件设计

那么,我们到底是怎么做的?为什么我们没有遵循众所周知的软件架构建议方法?

就这个问题,我与来自其他 FANG 技术公司(即 Facebook、亚马逊、Netflix、谷歌)以及小型初创企业的同行工程师进行过讨论。事实证明,大多数团队和项目(无论具体规模如何)都采用了以下几种设计与实施方法:

  1. 从业务问题入手。 我们想要解决什么问题?我们希望构建怎样的产品?为什么?我们如何衡量成功程度?
  2. 通过头脑风暴探寻合适方法。 汇聚团队并通过充分对话找到可行的解决方案。尽量控制头脑风暴的对话规模,先从宏观问题开始,再逐步落地至具体需求。
  3. 通过白板探寻合适方法。 将团队聚集在一起,由一个人负责汇总团队提出的整体方法。我们应该能够在白板上明确阐述系统 / 应用程序的架构,同样首先从宏观起步,并在必要时深入探讨。如果发现解释过程存在困难或者无法表述清楚,则证明细节还需要进一步打磨。
  4. 根据白板上的说明,通过简单的文档与图表对内容进行归纳。 尽量不使用那些晦涩难懂的术语:确保初级工程师们也能很快理解文档的表意。另外,使用清晰易懂的语言。在 Uber,我们使用 RFC 类文档并配合一套基础模板。
  5. 讨论权衡取舍与替代性方案。 良好的软件设计与理想的架构,在本质上就是做出了正确的权衡取舍。设计选择本身并没有好坏之分,一切都取决于背景与目标。你的架构是否被划分为多项不同服务?为什么不使用大型整体服务,毕竟这能带来其它一些优势,比如更直接且更快的部署方式。再有,你是否选择使用新功能扩展服务或模块?对每一项服务或模块的选择做出权衡,充分评估既定方法的优势与缺点。
  6. 在团队 / 组织之内传阅设计文档并整理反馈意见。 在 Uber,我们一直坚持向所有工程师发送软件设计文件,直到工程师队伍达到约 2000 人级别。现在我们的规模更大了,但设计文件的传阅范围仍然很广——当然,我们同时也会考虑信噪比平衡问题。我们鼓励大家提问并提出替代性方案。另外,设定合理的时间限制讨论反馈内容,并酌情将其纳入考量。某些直接反馈可能会当场解决,而更具体的反馈则可以由相关人员协商处理。

为什么我们的方法跟软件架构文献中的说法有这么大的差别?

实际上,对于大多数架构指南而言,我们的方法在原则上并没有多大区别。几乎所有指南都建议从业务问题起步,继而概述解决方案与权衡结论:我们也是这么做的。我们的区别,在于没有使用那么多架构师或者架构文献所强调的高复杂度工具。我们尽可能只选择简单的工具,例如 Google Docs 或者 Office 365 等,同时保证设计记录简洁明确。

我认为,这种方法与相关企业的工程文化息息相关。高度自治加层次分明,是这些科技企业与初创企业的共同特质:这些特质,在相对比较传统的公司内则很少见到。正因为如此,传统企业才必须在流程驱动设计当中遵循更为严格的规则,以进行更多“符合常识的设计”。

以银行与汽车制造企业为例,开发人员几乎无权跨越上级提出任何关于架构的决策,全部相关工作都由不同级别的多位架构师负责,而他们也需要随时监督多个技术团队。这就让整个流程变得相当缓慢,架构师本身也往往被大量请求吞没。正因为如此,常见架构文献中才提到尽量使用标准工具、整理出更加正式的文档,希望借此让系统设计思路更为清晰。再有,这些文档还强化出一种自上而下的工作执行思路,毕竟在架构师的约束之下,普通工程师根本就无权对当前采取的正式方法或者决策提出质疑。所以,他们通常也就懒得费那个心。公平地讲,传统企业同样希望开发人员之间能够更多交换资源与意见,从而在短时间之内灵活分配人员以应对不同项目,只是对他们来讲这样的目标很难实现。考虑到这一点,我们在不同环境中使用不同工具的灵活作法其实也没那么离经叛道。

要简单、术语少的软件设计,不要僵化的架构模式

设计系统应该始终秉持简单为先的目标。 系统越简单,理解难度也就越低,越易于发现问题,实现门槛也就更低。另外,语言描述越清晰,设计思路也越容易为他人所接受。因此,请避免使用那些团队成员无法理解的术语:即使是经验最少的成员,也应该能够弄明白团队到底在干什么、又为什么这么干。

干净的设计类似于干净的代码:易于阅读,易于理解。编写干净的代码,我们可以选择多种可行方法;但是,很少有人会建议在代码开发之初就采用 Gang of Four 设计模式。相反,干净代码的起步工作也同样单纯:单一责任、明确命名与易于理解的约定。这些原则也同样适用于干净的架构。

既然是这样,那么架构模式还有什么意义? 我认为架构模式的意义跟编码设计模式差不多,主要负责为我们提供如何改进代码或者架构的基本思路。在编码模式方面,当我发现一种模式时,往往会精神一振,尝试深入探索并将其与单例模式联系起来。但是,我可不打算硬性上升到“抽象生产模式”的高度。一般来讲,只要我能弄明白这种模式的作用,并搞清要如何将其广泛起效就足够了。我承认,我也花了不少时间研究并尝试理解 Gang of Four 设计模式,但是需要强调:这些对我编码水平的提升,远不及从其他工程师那里得到的反馈。

同样的,了解常见架构模式也是好事:这有助于简化同事之间的讨论流程,确保大家能够以相同的方式沟通并相互理解。但是,架构模式本身并不是目标,也永远不该被用于取代那些真正简单的系统设计方法。在设计系统时,我们可能会意外发现自己用到了某种众所周知的模式:这挺好的。但这不是强制要求,大家应该放松心态选择自己的办法。总而言之,千万别把架构模式当成“锤子”,到处寻找合适或者不合适的“钉子”来敲。

架构模式的出现,源自工程师们在观察到某些情况下存在着共通的设计选择倾向,而且这些设计选择同样会经过命名、记录以及广泛讨论。换言之,架构模式是解决方案出现之后才产生的工具,旨在让其他开发者能够更轻松地解决问题。作为一名工程师,大家的目标应该是更好地解决问题,让解决方案变成自己的有力工具,而不是强行运用那些时髦的架构模式,然后祈祷它们真能适合你的实际需求。

如何更好地设计系统?

我听说,很多朋友都希望了解如何提升自身在架构与系统设计方面的水平。有些经验丰富的从业者会推荐大家阅读与架构模式以及软件架构相关的书籍。当然,多读书肯定是好事,一般书籍的内容在深度上要远远超过网站上的帖子;但我个人的建议是,亲自动手永远比单纯阅读效果更好。

  • 召集同事,用白板解释你的设计方法。 阐述你正在做什么,以及为什么要这么做,同时确保同事们能够真正理解。在过程当中,请认真倾听他们的反馈。
  • 把你的设计思路整理成一份简单的说明文档,并与其他团队成员分享以征求反馈意见。 无论你手头的工作有多简单或者说多复杂,做做总结都是必要的环节。请以方便自己及他人理解的方式整理文档,Uber 公司就一直有这种良好的习惯。另外,在分享中也要对反馈意见敞开胸怀,允许大家通过 Google Docs 或者 Office 365 等平台添加评论与注释,借此了解他人的想法与疑问。
  • 采取两种不同的方式,并对两种设计方案作出比对。 大多数在设计架构时,往往只会拿出一套方案,也就是他们脑海中首先浮现的处理办法。但是,架构选择绝不是非黑即白的,因此请尝试整理出第二种可行的设计成果。对二者加以对比,并说明为什么其中一种比另一种更好。最后,简要列出第二套备选设计方案,并在讨论中确定为什么不予采用。
  • 明确说明你的权衡思路,为什么要做出这样的权衡,以及你据此进行的优化。 明确强调当前存在的约束条件,并将其充分纳入考量。
  • 审查其他人的设计,取其精华。 假设你所在的企业鼓励大家通过白板、会议或者文档的形式分享自己的设计,那么请务必多花心思从中汲取营养。在审查期间,大多数人只是被动接受现有方案,这是一种单向的观察行为,毫无实际意义。相反,我们应该弄清那些自己不太明确的部分,包括向发布者询问他们是否考虑过其它替代性方案。此外,询问他们采取了怎样的权衡取舍,以及假设中的约束条件。合适的时候不妨唱唱反调,提出可能更为简单的选项——即使未必更好——然后听取对方的看法。即使最终没有被选中,这样的思维过程也足以带来实际价值并帮助我们学到更多。

最好的软件设计应当简单易懂。 在启动下一个新项目之前,请不要再思考“我该如何构建这套系统、应该采用哪些经过实践验证的模式,又选择哪种正式方法进行记录?”相反,想想“我要怎样才能以他人更易于理解的方式,拿出最简单的设计?”

最后还得强调一句,软件架构最佳实践、企业架构模式以及系统描述的正式方法都是非常重要且实用的工具,相信总会有合适的场景让它们发挥作用。但在设计系统时,请从简单始、以简单终,尽可能避免一切会无谓提高复杂度的架构与正式工具。

原文链接:

https://blog.pragmaticengineer.com/software-architecture-is-overrated/

今日荐文

点击下方图片即可阅读

微软内部薪资泄露,揭秘大型科技公司薪酬运作的关键细节


活动推荐

AI 落脚于不同领域,企业所面临的问题也不尽相同。无论是 AI 中垂直技术的应用,还是应用领域的垂直选择,如何选择合适的赛道成为当务之急。ArchSummit全球架构师峰会(北京站)2019大会中,独家设置了“提升效率的AIOps“专题,为你讲解智能运维的那些事!目前8折购票,限时立减1760元,团购更便宜哦~ 

了解详情请联系票务经理灰灰:15600537884 ,微信同号。


你也「在看」吗?👇

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存