HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

软件架构被高估,清晰简单的设计被低估

  • 2019-09-29
  • 本文字数:4059 字

    阅读完需:约 13 分钟

软件架构被高估,清晰简单的设计被低估

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


我的职责是设计和构建大型系统。我参与重写了 Uber 的分布式支付系统,设计并交付了 Skype on Xbox One,开源了 Uber 的移动架构框架RIBs。所有这些系统都进行了彻底的设计,经过多次迭代和大量讨论。然后,这些设计被记录到设计文档中,在我们开始构建之前分发出去,从而获得更多的反馈。


所有这些系统的规模都很大:有数百名开发人员在构建它们——或者以它们为基础进行构建——并且它们支撑着每天数百万人使用的系统。它们不仅仅是绿地项目。重写的支付系统就是用于替换两个已有的支付系统,有几十个系统、数十个团队在使用它们,但所有这些都没有对业务产生任何影响。重写 Uber App 是一个由数百名工程师同时参与的项目,他们将现有的功能移植到一个新的架构中。


让我先说些可能会让你觉得吃惊的事。首先,这些设计都没有使用任何标准的软件架构规划工具。我们没有使用UML,没有使用4+1模型,没有使用ADR,也没有使用C4依赖关系图。我们创建了大量的图表,但是没有遵循任何严格的规则。只是使用了普通的方框和箭头,类似于这个描述信息流的图或这个概括类结构和组件之间关系的图。同一个设计文档中的两个图经常会有不同的布局,并且经常由不同的工程师添加和修改。


其次,负责设计的团队中没有架构师。没有IT架构师企业架构师。没错,Uber 和 Skype/微软都没有袖手旁观的软件架构师职位。级别较高的工程师和普通工程师一样,仍然需要定期编写代码。对于所有的项目,我们都有经验丰富的工程师参与。然而,没有人专门负责架构或设计。经验丰富的开发人员确实推动了设计过程。不过,即使是最初级的成员也在设计过程中进行了输入,他们经常会挑战决策,并提供其他可供讨论的替代方案。


第三,我们实际上没有引入常见的架构模式以及常见的软件架构文献中引用的其他术语,比如Martin Fowler的架构指南。没有提到微服务、无服务器架构、应用程序边界、事件驱动架构等。其中一些在头脑风暴时确实提到过,但是,没有必要在设计文档中引用它们。

科技公司和初创企业的软件设计

那么,我们是如何完成任务的呢?为什么我们不遵循著名的软件架构方法所建议的方法呢?


我曾与其他科技公司(Facebook、亚马逊、Netflix、谷歌)以及规模较小的初创公司的同行们讨论过这个问题。大多数团队和项目无论大小,都采用类似的设计和实现方法:


  1. 从业务问题入手。我们要解决什么问题?我们要设法构建什么产品?为什么?我们如何度量成功?

  2. 通过头脑风暴找出方法。与团队一起,通过多次会议,找出可行的解决方案。务必保证这些头脑风暴的规模要小。从高层开始,逐步下降到较低的层次上。

  3. 借助白板说明方法。把团队聚集在一起,让一个人绘制出团队趋向于采用的方法。你应该能够在白板上清楚地解释你的系统/应用程序的架构,从高层开始,根据需要逐步深入。如果你觉得解释有困难或者不够清楚,就需要在细节上做更多的工作。

  4. 根据你在白板上的解释,使用简洁的文档和图表详细描述设计。尽量少用术语:要让初级工程师也明白它的意思。用清晰易懂的语言写下来。在 Uber,我们使用一个带有基本模板的类似 RFC 的文档。

  5. 讨论权衡可选方案。良好的软件设计和架构重点在于做出正确的权衡。设计选择本身没有好坏之分:它完全取决于上下文和目标。架构是否要划分为不同的微服务?说明一下为什么你决定不使用单体架构,它可能有其他一些好处,比如部署更简单更快速。你是否选择使用新功能扩展服务或模块?权衡构建单个服务或模块的选项,以及这种方法的优缺点。

  6. 在团队/组织内分发设计文档并获得反馈。在 Uber,我们曾经把所有的软件设计文档发给所有的工程师,直到我们的工程师人数达到大约 2000 名。现在我们的人数更多了,我们仍然广泛地分发设计文档,但是我们已经开始更多地平衡信噪比。我们鼓励人们提出问题并提供替代方案。要根据实际情况设定合理的反馈时间限制,讨论反馈意见,并根据需要加以采纳。简单明了的反馈可以现场快速处理,而更复杂的反馈现场处理也可能会更快。


为什么我们的方法与软件架构文献中经常提到的方法不同?实际上,我们的方法与大多数架构指南在原则上并没有太大的不同。几乎所有的指南都建议从业务问题开始,概述解决方案并进行权衡:我们也是这样做的。我们没有使用许多架构师或架构书籍提倡的更复杂的工具。我们使用最直接的工具(如谷歌 Docs 或 Office365)尽可能简单地记录设计。


我认为,在这些公司中,我们的方法的主要区别在于工程文化。自主性高和层级少是科技公司和初创企业的共同特点:对于更传统的公司来说,有时并非如此。这也是为什么这些地方使用更严格的规则进行更多的“基于常识的设计”,而不是流程驱动的设计。


我知道一些银行和汽车公司,它们的开发人员在没有得到高层架构师的批准之前,不愿做出任何架构决策,而这些架构师负责管理多个团队。这会是一个比较缓慢的过程,架构师可能会被许多请求淹没。因此,这些架构师创建了更正式的文档,希望通过更多地使用常见文献中介绍的工具使系统更清晰。这些文档还强化了自上向下的方法,因为对于非架构师工程师来说,质疑或挑战已经用正式方法记录下来的、他们不是很熟悉的决策更令人生畏。所以他们通常不会这么做。公平地说,这些公司常常希望使开发人员成为更容易替换的资源,以便他们可以在短时间内重新分配人员从事不同的项目。不同的工具在不同的环境中可以更好地发挥作用,这应该不足为奇。

简单、无术语的软件设计胜过架构模式

系统设计的目标应该是简单。系统越简单,理解起来就越容易,就越容易发现问题,实现起来也就越简单。使用的描述语言越清晰,设计就越容易理解。避免使用团队中每个成员都不理解的术语:即时是经验最少的人也应该能够同样清楚地理解设计。


简洁的设计类似于简洁的代码:易于阅读和理解。有许多好方法可以编写出简洁的代码。然而,你很少听到有人一开始就建议将设计模式应用到你的代码中。简洁的代码从单一职责、清晰的命名和易于理解的约定开始。这些原则同样适用于简洁的架构。


那么,架构模式的作用是什么?我认为它们与编码设计模式同样有用。它们可以为你提供关于如何改进代码或架构的思路。对于编码模式,当我看到一个单例模式时,我就会注意到它;当我看到一个类仅充当执行调用的外观时,我就会扬起眉毛,深入研究。但我还没有想到“这需要一个抽象工厂模式”。事实上,在处理了大量依赖注入之后,我花了很多时间来理解这个模式的作用,并且终于在某个时刻恍然大悟——这实际上是这个模式非常常见并且非常有用的少数几个领域之一。我还得承认,虽然我花了很多时间阅读和理解 GoF 设计模式,但与我从其他工程师那里得到的代码反馈相比,它们对于我成为一名更好的程序员的影响要小得多。


类似地,了解常见的架构模式是一件好事:它有助于缩短与他人讨论的时间,他们和你一样理解那些模式。但是架构模式并不是我们的目标,它们也不能代替更简单的系统设计。在设计系统时,你可能会无意中应用了一个众所周知的模式:这是一件好事。后续你要参照这个方法就更容易了。但是,你最不希望看到的是使用一个或多个架构模式,把它当成一把锤子,为了用它而到处找钉子。


工程师们观察到,人们在某些情况下会做出类似的设计选择,并且这些选择的实现方式也非常类似,于是,就诞生了架构模式。然后,这些选择被命名、记录,并被广泛地讨论。架构模式是在制定解决方案后出现的工具,目的是简化工程师的工作。作为一名工程师,你的目标应该更多地是制定解决方案并从中学习,而不是选择一个闪亮的架构模式,希望它能解决你的问题。

如何更好地设计系统?

我听到许多人询问如何更好地架构和设计系统。一些有经验的人会推荐你阅读架构模式和软件架构方面的书籍。我肯定也推荐阅读——尤其是书籍,因为它们比一篇短文更有深度——但我还是有一些建议,这些建议比单纯的阅读更具实践性。


  • 拉过一名同事,在白板上写下你的设计方法。写出你在做什么,为什么要这么做。确保他们能理解。当他们能理解的时候,征求他们的意见。

  • 将你的设计详细记录在一个简单的文档中,并与你的团队分享,寻求反馈。不管你正在处理的事情多么简单或复杂,可能是较小的重构,也可能是大型项目,总结一下。采用一种对你而言有意义的方式,一种别人能理解的方式。为了帮你寻找灵感,我在这里分享了我在 Uber 看到的做法。与团队共享时采用一种可以评论的格式,如谷歌文档、Office365 等。让人们添加他们的想法和问题。

  • 设计两种方案,并进行对比。大多数人在设计架构时都只采用一种方法,就是突然出现在他们脑海中的方法。然而,架构并不是非黑即白的。提出第二个同样可行的设计。对比两者,解释为什么一个比另一个更好。简要列出第二种设计作为备选方案,并说明为什么决定不用它。

  • 要清楚你所做的权衡,为什么要做这些权衡,以及你优化了哪些东西。要清楚存在的约束,并且必须考虑到这些约束。

  • 评审别人的设计,并取长补短做到更好。假设你们有这样一种文化,人们通过白板、会议或文档来分享他们的设计,那么你就能从评审意见中了解到更多的东西。在评审过程中,大多数人只是试着接受一些东西,成为单向的观察者。我们不能局限于此。相反,对于不清楚的部分要通过提问来弄清楚。询问他们考虑过的其他选项。问他们做了哪些权衡,假设了哪些约束条件。要唱反调,提出另一个可能更简单的选项——即使不是更好的选项——问问他们对你的建议有何看法。即使你没有像设计展示者那样思考得那么深入,你仍然可以带来很多有价值的东西并学到更多的东西。


最好的软件设计是简单易懂的设计。下次启动一个新项目时,不要想着“我将如何构建这个系统,我应该使用哪些经过实战检验的模式,以及我应该使用哪些形式化的方法来记录它?”,而是要想一想“我怎么才能想出一种任何人都很容易理解的、最简单的设计?”


原文链接:Software Architecture is Overrated, Clear and Simple Design is Underrated


2019-09-29 13:464497
用户头像

发布了 729 篇内容, 共 466.4 次阅读, 收获喜欢 1544 次。

关注

评论 1 条评论

发布
用户头像
说出了真话
2019-09-30 09:39
回复
没有更多了
发现更多内容

软件测试 | 测试开发 | 记一次connection-reset-by-peer问题定位

测吧(北京)科技有限公司

测试

禅道的Bug管理流程介绍

禅道项目管理

测试 禅道 bug管理

软件测试 | 测试开发 | web自动化测试-文件上传与弹框处理

测吧(北京)科技有限公司

测试

如何让用户用好你的在线设计协作工具?帮助中心来解决

Baklib

为企业产品实现随时随地的客户服务

Baklib

产品 企业 客户服务 帮助中心 降低成本

高效的知识管理应具备的元素

Baklib

知识管理 高效 知识库

关于iPhone 14 Pro 的灵动岛设计的思考

宇宙之一粟

iphone 思考 设计 9月月更

2022年汽车智能座舱市场分析

易观分析

汽车 智能座舱

Sophon AutoCV Q&A大放送:如何加速视觉模型生产和落地(上篇)

星环科技

Elasticsearch安全又双叒叕出问题? 搜索引擎该怎么选

星环科技

如何做有价值的企业知识管理?

Baklib

创业 知识管理 企业 知识库

软件测试 | 测试开发 | Real Distributed APEX

测吧(北京)科技有限公司

测试

自动化测试如何区分用例集合

老张

自动化测试 测试用例

JavaScript之面向对象

楠羽

JavaScript 笔记 9月月更

Sophon AutoCV Q&A大放送:如何加速视觉模型生产和落地(下篇)

星环科技

SQL 改写系列十:半连接转内连接

OceanBase 数据库

优雅的MVC思想

叫练

原生实现异步处理利器 —— Observable

掘金安东尼

前端 9月月更

星环科技多模型数据统一存储的大数据分布式存储平台方案分享

星环科技

ODC 3.4.0 现已上线,让数据库开发更简单

OceanBase 数据库

软件测试 | 测试开发 | 测试人生 | 资深外包逆袭大厂测试开发:面试官的“歧视”表情深深刺痛了我

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | Android动态权限详解

测吧(北京)科技有限公司

测试

软件测试 | 测试开发 | 使用 adb 对 Android 声音控制全面适配

测吧(北京)科技有限公司

测试

【9.9-9.16】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

5 大核心能力+1 套全局防护策略,星环科技 Defensor 构建企业数据安全护城河

星环科技

热烈祝贺致欧家居获2022 IDC中国未来企业大奖「未来数字基础架构领军者优秀奖」

OceanBase 数据库

出海人反脆弱,那些遭遇「刺客」突袭的虐心瞬间

融云 RongCloud

白皮书 程序员、

设计模式简要介绍

六月的雨在InfoQ

Java 设计模式 单例模式 23种设计模式 9月月更

软件测试 | 测试开发 | 测试人生 | 双非院校,从外包到外企涨薪85%,他的涨薪秘籍全公开

测吧(北京)科技有限公司

测试

MobTech袤博科技接入全国SDK管理服务平台,共建数智安全生态 | 新闻速递

MobTech袤博科技

大数据 数据安全

星环科技发布工业互联网解决方案,场景化赋能制造业转型升级

星环科技

软件架构被高估,清晰简单的设计被低估_文化 & 方法_Gergely Orosz_InfoQ精选文章