做开发的都应知道的关于架构的五件事

2018-04-03 11:53:52 浏览数 (1)

回想起2010年的时候,我还曾写过一篇标题为“你是一名架构师吗?”的文章,里边阐述了软件开发者和软件架构师的区别与联系。

尽管都已经过去八年之久,并且整个行业在很多方面都发生了变化。

但看起来软件开发团队们依然对一些基础问题充满了争议,尤其和软件架构有联系的那些方面。

考虑到我们正在构建的软件系统的分布式特性以及团队构建的分布式特性,这些问题可以说比以前更重要。

本文就这个主题做一个简短的阐明,并揭穿一些神话,以下是每个软件开发人员应该了解的关于软件架构的五件事情。

关键要点

  • 鉴于我们正在构建的软件系统的分布式特性以及团队构建的分布式特性,了解软件架构的基础知识比以往更加重要。
  • 前期设计有个甜蜜点,不应该太多或根本不做,而应关于通过重要决策和权衡来影响软件系统“形状”。
  • 优秀的架构师是开发团队的积极成员(master builders),从写代码、合作到指导,为团队提供技术领导。
  • 关于软件架构的沟通是一个挑战。 C4模型是一个不错的沟通工具,从上下文图( context diagram)开始,一直延伸展开到系统的更多技术方面。
  • 与一些流行的观点相反,优秀的架构和敏捷并不冲突。

1.软件架构不是关于大而周全的设计

传统的软件架构总是与“大型设计”和“瀑布式交付”这些关键词相关联,团队可以确保在编写任何代码之前考虑到软件设计的每一个元素。传统的设计就是如此的详细和具体。

2001年,“敏捷软件开发宣言”提出,要重视“按计划进行改变”,然后人们就把“面对面价值为准”误解为直接“不做计划”。于是,你也看到了,最终的结果是,一些软件开发团队已经从前期做大设计转为不做前期设计。

显然两个极端都是愚蠢的,如果我们稍微柔和一点,就会很容易的发现一个甜蜜点,一个平衡点。现在让我们转变一下观念,如果我们认为前期设计没有必要必须要产生一个完美的结果,而是认为前期设计只是一个起点并且是为了给团队指明方向。

那么这个步骤(前期设计)就可以为团队增加巨大的价值,它可以让人们知道他们将要去做什么以及是否要去做某件事。

为了达到软件设计,你需要做出一些设计决定。在讨论架构与设计的区别时,Grady Booch告诉我们“架构代表着重要的决定,其重要性是以变化成本来衡量的。”换句话说,哪一个决定在晚些时候变化是很昂贵的?接下来,考虑前期设计的一个好方法就是确保你已经理解了与“重大决策”相关的权衡。

这些重大决策通常与技术选择和结构(即分解策略,模块化,功能边界等)有关。比如,如果你正在构建一个单体软件系统,编程语言的选择就是你要考虑的“技术选择”之一。

但如果你是采用微服务架构,那么编程语言的选择可能并不是你关注的,你可能会做一些其他的“技术选择”(各种方案的权衡)。同样,采用“六边形”架构可以使你的业务逻辑与你的技术选择分离开来,但是同样存在权衡。

因此,前期设计过程应该是理解影响软件系统形状(长啥样)的重要决策,而不是理解数据库中每一列的长度。实际上,我希望团队真正了解他们将要构建的内容,他们将如何构建它(这里说的是抽象层面,更高层次的),以及他们设计的内容是否有很好的落地的机会。这些都是可以通过标识出最高优先级的风险并酌情减轻风险来实现,必要时还需要编写代码。总之,前期设计应该是把成功的可能性叠加在你的利益之上。

2.每个软件团队都要去考虑软件架构

我刚刚描述的内容适用于每个软件团队,从一个在车库里建立一个初创公司的1人团队,到拥有数百名开发人员的全球分布的团队。不管你是多大规模的团队,你都要去设置起点和确定方向。不这样做往往会导致混乱 - 结构不良,内部不一致的代码库(定型的“大泥球”)难以理解,难以维护,并且可能不能满足一个或多个重要的质量属性如性能,可伸缩性或安全性。总之,每个团队都需要去考虑软件架构。

ps:特别是微服务架构下,你所在的业务的拆分是面向全公司的,得做出一些设计上的努力。

3.软件架构的角色是关于coding、指导和合作的

许多人对软件架构师的印象是传统的“象牙塔”软件架构师向一个毫无疑问的开发团队口授指令,就像第一个跑步者将在接力赛中传递接力棒一样。

其实并不需要,也并不应该这样做,许多优秀的软件架构师更喜欢使用有助于他们编码,指导和协作设计的方法。

我遇到的大多数优秀的软件架构师也是优秀的开发人员,他们仍然喜欢编码,而且他们也并不想放弃写代码。考虑到技术变化的速度,人们也很容易失去技术。我倾向于认为软件架构师应该是“主构建者(master builders)”,其含义是他们可以并且尽可能将代码编写作为团队的一部分。作为团队的一部分,编写代码往往会使软件架构师的角色变得更加容易,因为你将更加了解正在构建的系统,其他开发人员会将你视为同行。

还值得一提的是,软件架构师角色不一定需要由一个人来完成。

一个人是一个好的起点,但架构师角色可以是许多人共同的合作努力。不过,请谨慎一些。

建议合作技术领导是容易的。然而具体落实到软技能却有时候很难。我一般会组成一个2-5人的架构组去设计一个软件系统。但我也曾目睹过其中的一些团队无法就有关设计和技术选择的决定达成共识。在极端情况下,群体因自我和人格冲突而分裂。关键是要了解你所拥有的团队,然后确定适当的技术领导的数量以及风格。

4. 你可以不用UML

软件体系结构的传统观点常常使人联想到巨大的UML(统一建模语言)模型的视图。这些模型试图捕捉每一个细节。不幸的是,建模和UML与前敏捷时代的“大设计先行”实践相结合的理念,近年来这些理念已经被团队抛弃了。在我去世界各地的旅行中,我遇到的团队中没有人知道UML的软件开发团队的比例正在增加。

现在很多人的共同建议是“只用白板上的方框块和线条”作为交流意见的方式。

不过多年来,我从我的软件架构积累中累积了大量的照片,而且我可以自信地说,作为一个行业,我们已经失去了交流软件架构的能力。我看到过你可以想象的每一个可能的图表;从难以辨认的随机彩色框和线的集合到字面上没有任何关于解决方案的图表。无法沟通软件架构的团队将无法开启我之前描述的起点,也无法确定方向。

我的解决方案是我称之为“C4模型”(上下文,容器,组件和代码:Context, Containers, Components and Code)的软件体系结构的抽象优先法。其实质是创建一套分层的,可缩放的地图来描述一个软件系统。对于任何给定的软件系统,你都可以创建一个系统环境(Context)图,描述系统如何适应周围的环境。然后放大系统边界以显示其中的容器 (Container)容器是一个可部署的,可运行的事物,就像在Web浏览器中运行的单页应用程序,服务器端Web应用程序,微服务,数据库模式,等等。如果有用的话,你可以进一步放大到每个容器(Container),以显示其中的组件(Component)最后,还可以选择放大每个组件(Container),以显示由它组成的代码(Code或叫“Class”)级别元素(类,接口,函数,对象等)。 C4模型是独立的符号,尽管我倾向于使用简单的“框和线”符号,但你也可以使用UML。

如果你的团队正在努力想要沟通软件架构,并且觉得白板/wiki上的图表开始变得难懂或者没有了感觉,那么建议你去c4model.com上找到更多信息,视频,示例图表和工具链接,值得一看。

5. 架构和敏捷并不冲突

“架构”和“敏捷”,很多时候还被人们误解为二者是相互冲突和竞争的,但事实并非如此。相反,一个好的软件架构可以提高敏捷性,帮助你拥抱并实施变革。比如需求变化,业务流程,合并等

什么样的架构是“好架构”,是一句两句说不清楚的,人们总是在争论,但无论如何,对于我来说,好的架构的核心特征是通过适当的分解策略实现模块化。

如果你经历过对现有的一大块的泥浆代码做改变的痛苦,那种看起来没有关联的代码库部分也一并被破坏,你就会明白,具有良好结构化的代码库(良好的模块化)是非常重要的。

我最近发现了一个很大的问题是,一些人采纳了乔治费尔班克斯在他的Just Enough Software Architecture一书中所说的“架构无关紧要的设计”。换句话说,他们采取了一种不必考虑权衡的架构风格。

在当今世界,这通常表现在采用微服务架构风格的团队,仅仅是对现有的单体代码库的进行反应,这简直是一团糟,不可取。

于是这些团队随后就创造了一个“分布式大泥球”,由以前的“单体大泥球”变成了“分布式大泥球”。事实证明,软件设计和分解的过程是非常重要的,不管你是在建造一个单体的或微服务架构。

不可能轻易的就拥有一个灵活的好架构。你需要一些有意识的设计努力,需要考虑权衡。这也是为什么用一些前期设计来作为起点至关重要的原因。

关于作者

Simon Brown 是一位专门从事软件架构的独立顾问,也是“Software Architecture for Developers”(开发人员友好的软件架构指南,技术领导力和敏捷性平衡)的作者。 他也是C4软件体系结构模型的创建者,这是一种创建代码映射的简单方法。 Simon在国际软件开发会议上经常发表演讲,并前往全球各地,帮助企业可视化和记录他们的软件架构。

0 人点赞