[关闭]
@xuemingdeng 2017-08-22T17:34:36.000000Z 字数 5833 阅读 936

软件架构图的艺术

架构


摘要:

架构图对于系统的设计和文档化来说都是很重要的。它们必须是自描述的,并且与代码保持一致性。为了保证利益相关者能够看懂架构图,需要遵循一些原则。

正文:

要点

  • 设计软件架构图并非一件轻而易举的事情,即使是很简单的一个架构图也可能会出错。有意义且具备一致性的架构图有助于为不同的利益相关者澄清事实,并达成共识。
  • 在大多数情况下,问题的根源并不在于是否使用了一门有效的架构描述语言(比如UML),而在于低估了架构图的重要性,转而依赖不恰当或不具备一致性的指导性原则,或者缺乏架构思维。
  • 在创建架构图的过程中,试着混合使用自动生成的图元和手动创建的图元,这样可以减少工作量,并且可以表达出各方面的关注点,覆盖到系统的各个层面。
  • 系统不断地发生演化,要维护更新架构图需要花费额外的精力。我们需要知道如何有效地应对这种情况,同时能够保持架构图的一致性和健壮性。
  • 现代的软件架构带来了更多的复杂性,这些都反映在了架构图上。

曾几何时,我们的每一个软件项目都需要一个架构图。不管我们是否遵循正式的架构模型(比如Kruchten 4+1、Rozanski & Woods等),都有必要通过图表来对应用程序的某些部分进行文档化。在软件架构里,这些图表一般都是按照某些视图进行设计的,这些视图本身就是模型的一部分,不过在这篇文章里,我倾向于使用架构图这个术语,因为它看起来不是那么正式,至于其他方面的内容并不会在这篇文章里涉及到。

作为一个软件架构师和技术培训师,从我的经验来看,不同项目之间以及同一个团队的不同开发人员之间创建架构图的方式也是很不一样的。我看到过很多问题,比如一致性问题、碎片化问题、信息粒度大小的问题,以及图表的外观问题。相比架构模型的正式和标准化,架构图倒是不必要那么正式或者遵循什么标准。

不过,架构图必须是自描述的,并且要具备一致性和足够的准确性,能够与代码相呼应。这也就是为什么架构师或软件工程师在创建架构图时需要依赖各种指导性原则,因为它们是理解应用架构(比如结构、元素、关系、属性、原则)的基石,同时也是具有不同技术背景和关注点的利益相关者的沟通基础。

当前架构图的不足之处

在深入展开说明之前,我想引用一句英语谚语:“一张图片胜过千言万语”。Wiki上解释说,“这句谚语的意思是,一个复杂的想法可以通过一张静态的图片表达出来,或者图片可以表达一个主题的意思,又或者图片比文字描述来得更加直接有效”。对于架构图来说也是一样的:如果它所导致的疑问比它能解释的问题还要多,那么它就不是一张好的架构图。一张好的架构图不需要多余的文字解释!

此处输入图片的描述
图片:一张不是很好的架构图一般会存在如下几个问题。

现在让我们来过一下不好的架构图都有哪些问题,这些问题会阻碍我们创建好的架构图。

方框或其他形状表示什么意思?

形状的边线表示什么意思?

线条或箭头表示什么意思?

线条或箭头表示哪一种类型的交互或关联?

颜色代表什么意思?

单独的元素或实体

费解的缩略语或含糊不清的名词

在架构图中详述技术、框架、编程语言、IDE或开发方法论

在同一个架构图里混杂运行时元素和静态元素

“稍后详述”或“稍后解释”

层级冲突或混合抽象

使用混乱或含糊不清的架构图表达过量的信息或无效的细节

在创建架构图时可参考的指南

除了上面列出的问题清单,还可以参考如下的一些指南来创建更好的架构图。

选择最优的架构图数量

保持架构图的结构一致性和语义一致性

避免架构图碎片化

保持架构图的可追踪性

在架构图旁边加上图例

使用架构描述语言(比如UML、ArchiMate等)会有不一样的效果吗?

关于如何在项目里使用正确的架构描述语言有很多不同的看法。有些人认为UML太过死板,用来做架构设计缺乏灵活性,在某种程度上我认同这个看法。有时候,在不依赖UML的profile和stereotype特性的情况下也能很好地完成架构图设计。至于说到其他的架构描述语言,我认为ArchiMate更加强大,相比UML,它更适合用来为企业系统建模。还有BPMN,它更专注业务流程的建模。对这些工具进行深入比较已经超出这篇文章的范围,所以不再累述。

在选择架构描述语言时,综合性和灵活性是首要考虑的因素。但据我所知,完全不使用架构文档的情况也很常见。有些人觉得创建架构文档是一件很无聊的事情,而且觉得它们没有什么意义。这样的项目应该不在少数。人们因为没有使用合适的架构描述语言,所以创建不出很好的架构图,相反,如果他们使用了更好的工具,结果可能会大不一样。但事实并非如此,实际上他们跟本不想去创建什么架构文档(包括架构图),更糟糕的是,他们可能不知道该如何创建架构图。这是我们首要解决的问题——了解文档的重要性以及如何创建它们(给软件工程师做培训),然后选择合适的工具。

在系统和架构发生变化时如何更新架构图?

更新架构图有几种方式,我将会介绍其中的三种。第一种,也是最简单的一种,就是直接从代码生成架构图。这样可以保证架构图与代码是一致的。不过目前的工具还不能完全支持这种方式,在没有人工介入的情况下,工具还无法基于代码生成精确且有意义的架构图。Len Bass说,“在最理想的开发环境里,只需要一个按钮就能得到我们想要的文档”。他指的就是自动生成架构图,但我们还远远没有达到那种程度。

第二种,先用建模工具创建架构图,然后生成代码骨架(比如组件或包、API),随后开发人员可以在骨架上添加代码。每次架构图发生变更,需要从架构图端重新生成代码骨架。

第三种,在每次加入新特性时手动更新架构图。为了保证代码与架构图的一致性,建议把更新架构图作为开发流程的一部分。不过我们不推荐这种方式,因为这样很容易造成架构图过时或出现不一致(比如开发人员总是忘记或者不想更新架构图)。

我的建议是混合使用现有的工具,结合手动和自动的方式来创建架构图。例如,尝试自动生成架构图,使用工具基于代码渲染出符合基本要求的架构图,不包含混乱无用的信息。架构图可以高度可变(比如可以适应频繁的开发变更,这类架构图一般具有较低层次的抽象),也可以是静态的。这类图表可以是上下文架构图、参考架构图、包图、类图、实体图,等等。不过有时候仅仅基于代码无法生成满足需求的架构图,所以在这种情况下,自动创建架构图不是理想的方式。这个时候需要手动建模作为补充,这类架构图包括时序图、状态图、并发图、部署图、运营图,等等。

现代架构(如微服务)对架构图有什么影响?

微服务或其他任何一个现代架构风格(如无服务器、事件驱动)只会影响到系统的结构、组件间的交互方式(比如组件间的关系)和原则。在我看来,我不认为架构风格会改变架构图原先的含义。不过,相比传统的系统(比如单体),我们所说的现代系统架构具有更高层次的复杂性,它们对架构描述和架构图确实会有一些影响,这些是我们需要注意的。我们需要考虑分布式组件(比如分布式微服务)、每种组件的类型、组件间的交互方式(比如边界、API、消息)、他们的生命周期以及从属关系。

综上所述,我们需要在架构图中体现系统的分解、开发、部署和运维。假设有一个包含了大量微服务的系统,它就会有很多的架构图,因为每个微服务都可能有自己的架构图。一致性(例如,改变一个服务的API会影响到其他服务,所有相关的架构图都需要做出修改)、碎片化(例如,一个架构图无法反映分布式服务的高可用性和性能)和横断面(例如,是谁在负责处理系统的监控或安全问题)问题会让人手忙脚乱。我们首要面对的挑战是如何进行良好的团队协作,不仅仅是开发,也包括后续的维护。

总而言之,现代系统的复杂性会带来额外的问题,它们会在架构图层面造成一定程度的影响。

关于作者

此处输入图片的描述Ionut Balosin是Luxoft的软件架构师,拥有十年以上的应用程序开发经验,专注性能调优和软件架构。他是开发大会的演讲常客,也是一名技术培训师。

查看英文原文: The Art of Crafting Architectural Diagrams

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注