软件架构指南 - martinfowler


当软件行业的人们谈论“架构”时,他们指的是软件系统内部设计最重要方面的一个模糊定义的概念。良好的架构很重要,否则将来添加新功能会变得更慢,更昂贵。
像软件世界中的许多人一样,我长期以来一直对“架构”一词持谨慎态度,因为它常常暗示了与编程的分离和不健康的浮夸。但我通过强调良好的架构是支持其自身发展的东西来解决我的问题,并且与编程密切相关。我职业生涯的大部分时间都围绕着好的架构是什么样的问题,团队如何创建它,以及如何在我们的开发组织中最好地培养建筑思维。本页概述了我对软件架构的看法,并指出了有关该站点架构的更多资料。

什么是架构?
软件世界的人们一直在争论架构的定义。对于某些人来说,它类似于系统的基本组织,或者最高级别组件连接在一起的方式。我对此的想法是通过与拉尔夫·约翰逊Ralph Johnson)进行电子邮件交流而形成的,他质疑这种措辞,认为没有客观的方法来定义什么是基础或高级别,更好的架构观点是专家开发人员的共同理解拥有系统设计。
架构的第二种常见定义是,它是“需要在项目早期做出的设计决策”,但拉尔夫也抱怨这一点,并说这更像是你希望你能早日对一个项目做出的决定。
他的结论是“架构是重要的东西。无论那是什么“。乍一看,这听起来很陈旧,但我发现它带来了很多丰富。这意味着在架构上思考软件的核心是:判决什么是重要的(即什么是架构),然后花费精力来保持这些架构元素的良好状态。要让开发人员成为架构师,他们需要能够识别哪些元素是重要的,识别哪些元素在不受控制时可能导致严重问题。

为什么架构很重要?
架构对于软件产品的客户和用户来说是一个棘手的主题 - 因为它不是他们立即感知的东西。但是,糟糕的架构是软件增长的主要原因 - 软件的元素阻碍了开发人员理解软件的能力。包含大量内容的软件更难以修改,导致功能更慢,更多缺陷。
这种情况与我们通常的经历相反。我们习惯于“高品质”的东西,因为它的成本更高。对于软件的某些方面,例如用户体验,这可能是真的。但是当涉及到架构和内部质量的其他方面时,这种关系就会逆转。高内部质量可以更快地交付新功能,因为可以减少阻碍。
虽然我们可以在短期内牺牲质量以便更快地交付,但是在残余物的形成产生影响之前,人们会低估这种残余物导致整体交付速度变慢的速度。虽然这不是可以客观衡量的事情,但经验丰富的开发人员认为,对内部质量的关注会在数周而非数月内得到回报。

应用架构
软件开发中的重要决策因我们正在考虑的环境规模而异。常见的规模是应用程序的规模,因此是“应用程序架构”。
定义应用程序体系结构的第一个问题是,没有明确定义应用程序是什么。我的观点是 应用是一种社会建构

  • 开发人员将其视为一个单元的代码体
  • 企业客户将一组功能视为一个单元
  • 一项倡议,那些有钱的人将其视为单一预算

如此宽松的定义会导致应用程序的许多潜在大小,从开发团队的几个人到几百人不等。(您会注意到我将大小视为涉及的人数,我认为这是衡量此类事物最有用的方式。)这种与企业架构之间的关键区别在于,存在着相当程度的统一目的社会建设。

参考:
应用边界
微服务指南
无服务器架构
Micro Frontends
GUI架构
表现领域数据分层

企业架构
虽然应用架构专注于某种形式的名义应用程序边界内的体系结构,但企业架构看起来跨大型企业的体系结, 这样的组织通常太大,无法将其所有软件分组到任何类型的内聚组中,因此需要跨多个具有许多代码库的团队进行协调,这些代码库彼此隔离开发,资金和用户彼此独立运行。
许多企业架构都是关于理解什么是值得中央协调的成本,以及协调应该采取什么形式。一个极端是中央架构组,必须批准企业中每个软件系统的所有架构决策。这些群体减缓了决策制定,无法真正理解如此广泛的系统组合中的问题,从而导致决策失败。但另一个极端是根本没有协调,导致团队重复工作,不能让不同的系统互操作,以及团队之间缺乏技能开发和交叉学习。
像大多数具有敏捷思维方式的人一样,我更倾向于在分权方面犯错,因此会更接近混乱的岩石而不是窒息控制。但是,在渠道的这一方面仍然意味着我们必须避开岩石,并以最小化所涉及的实际成本的方式最大化地方决策。

参考:
企业架构师加入团队
企业架构师在精益企业中的角色
产品超过项目
建筑师电梯 - 访问较高楼层

​​​​​​​
 

HN评论摘要
1.我的观点是,Martin Folwer的最大贡献确实是文档,并定义了词汇表,以便围绕企业中经常遇到(但可能是普通的)问题进行讨论应用开发。他并没有试图开辟新天地,但我很高兴他的作品存在。

下面是关于失血模型和充血模型的争论,MF是支持充血模型的,
2. 我认识一个人认为Folwer在很多方面都是错的。这个人现在是大公司的架构师(FAANG),之前他做过一些很棒的项目,所以我当然相信他。例如,他认为贫血模型是正确的方法,并且将方法放入数据对象是错误的。不幸的是他还不想写一本书,所以我不能透露任何东西,但我只想强调一个优秀的工程师不应该盲目相信任何东西,即使它似乎是由一个受欢迎的作者写的。我自己,读了他的重构书,这很棒。

3. 我不明白贫血领域模型现在是多么无关紧要,尤其是在许多软件从业者似乎都在进入领域驱动设计的时代。在微服务时代,确定明确的上下文边界非常重要。“逻辑生活在多种服务中”听起来更像是一种设计坏气味。在这种情况下,即使非常简单的业务需求的变化也可能意味着系统的多个部分发生变化,这可能意味着对许多不同服务进行多次重新部署。还意味着更复杂的集成(甚至是e2e)测试。 

4. 首先,贫血模型在服务环境中运作良好。您不能将业务规则作为数据实体的一部分,然后从一个网页发送到另外一个Web服务,。所以这些贫血模型在这世界上还是有一个位置的。
微服务仍然是服务。因此,我们始终验证跨越信任边界的数据 ,执行该验证的规则不能随数据一起传播。
如此内疚,因为贫血使我感到......奇怪。(banq注:这是将充血和贫血对立,作为充血模型是业务体现,当数据需要传播时,应该变成值对象或失血模型传播,验证规则还是在充血模型实体中,两者共存,而不是二选一,将网页具有UI模型或持久层模型、接口模型与领域模型分离。)

5. Folwer跳过了很多步骤并且做了很多断言。以下是其书籍《重构》的摘录:
>软件的性能通常仅取决于代码的几个部分,而其他任何地方的变化都不会产生明显的差异。
>因此,我对重构性能的总体建议是:大多数时候你应该忽略它。如果您的重构引入性能减慢,则首先完成重构并在之后进行性能调整。
这种“偶然”缺陷的缺点只是使福勒的所有写作都像营销之类的事情

关于软件是不是工程的争论:
6. 计算机科学不是一门科学,软件工程也不是一门工程学。他的指南更像是写作指南,缺乏数据。

7. 许多编程更多的是艺术或工艺而不是工程。
例如,机械师与工程师之间的区别是什么?他们经常在同一个项目上工作,似乎也在做同样的事情。在我看来,机械师遵循经验法则,眼球设计等。工程师应用数学并导出设计,或使用数学检查设计。机修工会说“这个梁看起来足够厚,可以承受负荷”,工程师可以进行计算,为负荷选择正确的厚度。
对于软件,程序员可以告诉您quicksort更快。工程师可以告诉您为什么它更快,并能够计算它的速度。

8. 软件工程的工程设计与机械工程是工程学一样。
唯一的区别是,使用软件,您的材料是描述。即你描述的东西,给计算机和计算机把它变成这个东西。
最后,世界上有一个物理实体(硬件),它根据您的描述(例如ATM)将自身变成一台独特的机器。
在机械工程中,您的材料是物理的,这可能使其更容易解释。

9. 软件开发既是一门艺术,也是一门科学。
就个人而言,我看到人们在一个项目的早期阶段就做出了糟糕的设计决定,这个项目将成为后来处理的主要问题。很容易看出,如果他们在一开始就花费了一点额外的质量,它会在几周甚至更短的时间内得到回报。
我也看到其他人花费太多时间在一开始就试图做到完美,没有任何东西可以交付,或者过度设计的解决方案会产生自己的技术债务形式。
每种情况都不同,因此您需要判断是否应用某人的建议。

10. 软件开发不需要成为一门艺术,也不需要成为一门科学。
科学的意思是使用数据和统计证据推动发展,艺术的意思是利用你的直觉和你的直觉来推动发展。
计算机是确定性系统。它是100%可预测的,并遵循一套精确的规则。软件开发适用于证明,逻辑和理论。如果问题空间可以用逻辑和公理理论来描述,那么你不需要做出由数据驱动的决策或你的直觉。
问题是当前的“理论”是不完整的,并非系统的所有部分都适合进行统计测量。因此,一个合适的系统架构师需要统一理论,科学和艺术,以形成一个连贯的系统架构框架。
Martin Fowler的问题在于他所有的东西都是100%艺术。它只是由直觉和流行语构成的东西。艺术在很大程度上是临时性的,并且涉及大量猜测工作,这些工作经常是错误的。人们认同Martin Fowlers的东西,因为他们在“肠道”层面上认同它。它“感觉”正确。你的感受不是做工程的好方法,当你别无选择时,你只依靠直觉。
Fowler也是一个面向对象的大型架构师。面向对象的东西是它没有理论或科学的基础,几乎是100%的艺术。这种模式从一开始就失宠,因为人们意识到他们倾向于在遵循模式时会构建过于复杂的系统,因为他们主要依靠他们的直觉来使用由同样有缺陷的直觉验证的原语来构建这些东西。 

11. >面向对象的东西是它在理论或科学上没有基础,几乎是100%的艺术。
绝对不正确。
OO的数据部分基于集合论,在数据库设计研究和类型系统中形式化。
OO的动态部分基于有限状态机。
数据抽象和信息隐藏部分基于barbara liskov的工作(她为此赢得了图灵奖) - https://en.wikipedia.org/wiki/Barbara_Liskov

12. 类型系统不是OO独有的,另外OO类型系统允许突变,这基本上根本不是集合论的所有部分。类型系统和数据库系统也没有形式化集合论。集合论来自数学。
>数据抽象和信息隐藏部分基于barbara liskov的工作(她为此赢得了图灵奖) - https://en.wikipedia.org/wiki/Barbara_Liskov
这与类型系统有关,然后与OOP有关。如果您阅读本文,请注意。她的论文没有数据,统计,形式理论,严谨,定理,证据或公理。因此虽然她获得了图灵奖,虽然这是一篇研究论文......但在我定义的意义上,它在很大程度上是“艺术的”。见这里的论文:
HTTP://citeseerx.ist.psu.edu/viewdoc/download DOI = 10.1.1.136 ...
请注意,她的论文很重要,我并不打折扣。但它更多地出现在设计领域,那么它就属于理论和科学领域。

13. 她在后来的书中提出了公理理论:
HTTPS://mitpress.mit.edu/books/abstraction-and-specification ...
她是否提出了OO界面设计的公理理论。
绝对不是艺术。
OO中唯一具有艺术性的东西(作为过去30年来实践它的人)正在寻找最初的一组对象。但是你会遇到任何技术问题。

14. > OO中唯一具有艺术性的东西(作为过去30年来实践它的人)正在寻找最初的一组对象。但是你会遇到任何技术问题。
OO具有很高的艺术性。它不仅仅是您决定的初始对象集,而是您必须决定每个单个对象的组成方式以及组成的对象。有很多关于如何组合对象以及何时编写组合的技术:继承,依赖注入,对象组合等等。在这些技术中,您仍然需要编写自定义代码,父级对象是什么,子对象是什么?什么属性?父级对象如何使用注入的对象?等等......你在设计系统而不是在理论框架内运作。这主要是艺术。
如果您在现有理论的框架内运行,您将能够更好地预测大规模系统的结果,但是因为在OO中您几乎为每个应用程序从头开始创建系统,这在很大程度上是不可预测的。
在数学中,所有定理都来自你选择的公理。几乎没有偏差的余地。
任何人为创建的系统都可以融入某种理论的框架中。虽然艺术设计的系统与源自理论知识的系统之间存在巨大差异。

关于DDD和微服务:
15.我分享一下我的经验。几年前,我正在为我的公司内部开发一个电子商务平台。我遵循Martin Fowlers关于使用DDD(域驱动设计)和微服务来构建应用程序的文章。应该是一个月的项目花了我们8个月!我不包括我阅读,理解和练习DDD及其周围概念的时间。每本DDD书至少500页或更多。他们都没有清楚这些概念,而且大部分都充满了绒毛。
我们的堆栈基于Phoenix,但它使用了一个名为Umbrella应用程序的概念(基本上是微服务模式)。一路走来,我遇到了很多障碍,我想我一定是做错了。因为,这就是这些作者一直对那些未能实施他们的讲道的人说的话。所以,我遇到了几个实际上比我更大规模地完成DDD的人,甚至他们分享了同样的失败和挣扎的经历和故事。尽管如此,我还是耸耸肩,认为这肯定是我们做错了而不是DDD / Fowler的教诲本身。与此同时,我们正在努力为我们的电子商务软件推出功能,因为我们基于DDD的微服务架构此时只是一个纸牌屋。然后,我终于打电话给我知道成功完成DDD的人并问他是怎么做到的。他说,一个受欢迎的DDD相关网站的作者之一曾提出为他的公司提供咨询。他们别无选择,只能雇用他,因为他们在这一点上投入了很多。过了一段时间,我开始会见一些这样的公司,他们的作者或某些供应商完成了他们的DDD设置。
然后BINGO,这一切都是有道理的 - 这些作者的大多数这些模式/捷径/发现/秘密酱很难被他们测试。这只是向您提供更多咨询和培训的一种方式。
几个星期后,我们在我们区域召开了一次临时的技术会谈聚会,我们遇到了更多跟随同样道路而失败的人。我们终于决定在一个周末做一个小黑客马拉松并完成我们的项目。最后,在距离Fri-Sun大约3天的时间里,我们使用单体架构完成了比DDD和微服务所做的更多的工作。今天,我的平台正在制作中,是一款引以为豪的单体应用,并且仍然很强大。
这可能是我学过的最昂贵的课程,但是我会记得很长一段时间。

16. Martin Fowler也写道:DDD适用于大型复杂软件。他还建议在微服务之前使用单体巨石。
如果你花一个月就能完成的东西,那就不大也不复杂,它不适合DDD或微服务。
微服务并不总是微观的。这是一个糟糕的名字。5-10的团队通常只在一个微服务上工作。1个微服务可以是数百万行代码。

17. 为什么你仍然每天都会在reddit和HN上看到人们彼此喋喋不休的几乎所有软件设计辩论。(并且软件使用争论甚至更糟。)他们的方法是最佳的,他们的对手是非常过度工程或不充分的工程。
人们喜欢坚持自己的偏好,更喜欢他们在经验不足和技术熟练时所偏离的东西,或者他们尊重的人使用的东西,或者几年前发生在他们的幻想或迷恋中的东西,或者是他们主观上的原因感觉不错。你可以在其他学科中看到完全相同的东西,包括艺术领域,以及完全相同类型的讨论板上的vitriol和货物结果。
好消息是你至少要接触到很多观点。如果有人只读了这个帖子中1/4的帖子,他们可能会被说服采取某种强硬立场,并发现自己走上了一条狭窄的道路。但是,如果他们阅读每一篇文章,他们都可以全力以赴,了解有多少激烈的分歧和模糊,并对正确或错误的做事方式更加怀疑和批评。

18. 在微服务架构中,故障处理很容易。状态管理很难。
在集中式数据库架构中,故障处理很难。状态管理很容易。

19.有时,从长期维护的角度来看,只有在足够长的时间内保持产品市场适应性的捷径才有意义。获得资金并生存。
Twitter就是一个很好的例子。每个人都同意Twitter做出一些糟糕的架构决策,导致频繁出现“失败、故障”。但最终,他们通过VC资金和后来的公共市场的组合获得了足够的资金来重新架构他们的系统。

20. 系统软件与企业软件没有什么不同。业务部分仅仅是技术性的。最大的区别通常是软件开发人员对业务规则没有深刻的理解。


关于UML讨论:
21. 从UML图表生成完整的代码。这就是整体推动OO的整体宏伟愿景。我认为这是“低代码”创业公司现在正在发生的事情。
整个想法是将全局决策(难以改变)分开 - 例如架构,什么类,每个类做什么,来自本地(例如使用哪种数据结构)。因此,您将使用UML进行全局决策,而不是使类的编程变成机械的写代码。
当然,客户看不到这一点。客户查看用户界面,以及是否正确实施了整个用例。因此,使用这些工具可能有所帮助。
让我们以架构为例,为什么人们会使用架构师?为什么架构师需要图表?业主是否会关心建筑师使用AutoCAD设计图表呢?

22. 如果您的经验告诉您UML适合您作为工具,那么,无论如何,坚持使用UML。即使有一种方法可以解决问题。如果你使用钢笔和纸张快速绘制东西,那么,如果这对你有用,那同样有效。我只是不会忽视一种方法,因为它的用处无法预先测量。现实实在太复杂了,有时候首先对这一切进行过多考虑并没有任何意义。