时序图,UML给软件开发带来的唯一好处
当你需要文档化系统的不同部分以及这些部分之间的交互方式时,时序图确实很有用。
时序图描述了系统内的操作,并与发送消息的内容和时间进行了映射。
在其最简单的形式中,时序图可以在用户登录银行应用程序时模拟用户与银行之间的消息和流程。在更复杂的形式中,时序图可以包括替代方案、选项和循环,以模拟条件流和分支流,例如,在登录过程还可以包括安全、验证和其他用户操作。
如果你没有广泛地使用过它们,那么你可能会在如下两种情况中听说过它们:一种是单独的,作为一种有用的图类型,在编写文档时需要考虑,另一种是作为统一建模语言 (UML) 的一个构件,UML 始于 20 世纪 90 年代末,现在已经很少使用它了。
在本文中,我将简要地挖掘 UML 的历史,这样我们就可以理解,时序图是如何以及为什么会在 UML 中的大多数图被扔进软件历史垃圾箱的情况下仍然能够存活下来。然后,我将展示为什么时序图仍然还有价值,以及我们应该如何充分地利用它们。
我的兴趣来自两个方面:我认为时序图被低估了且并未被充分利用,我认为时序图是 MermaidChart 的理想用例,因为它使用户能够选择非正式的简单性,而不必使用像 IBM 的 Rational Rose 这样的旧工具所产生的刚性复杂性。
UML 最初出现在 1997 年,正如 Martin Fowler 在前几年所写的那样,其主要目的是“消除笼罩在面向对象世界上空的图形建模语言的混乱”。一个基本问题(一个在软件历史上反复出现过很多次的问题)是存在着混乱和困惑,人们真的希望引入一个能够提供清晰的标准。
Rational 软件公司于 1994 年开始开发 UML;对象管理组织(OMG)于 1997 年将其作为标准接受;国际标准化组织(ISO)于 2005 年将其作为公认标准。
UML 的兴起带来了兴奋和批评,即使它已成为了一种标准(至少在书面上是)。许多人喜欢它,但更多的人认为它有问题,任务无论是 UML 本身,还是人们改如何使用它都存在问题。2004 年,波音公司软件架构师的一篇文章《UML 狂热之死》抓住了其中的一些抱怨。
在文章中,作者写道:“没有其他技术能像 UML 那样迅速而深入地渗透到软件工程的生命周期中”,并认为 UML 已经成为没有软件经验的人设计和控制软件开发过程的工具。
在此后的几年里,更是出现了一些讣告,包括 Ivar Jacobson 在 2018 年的一篇文章(在 UML 成为标准时,他已是 Rational Software 的副总裁);Hillel Wayne 在 2021 年的一篇文章(他采访了当时的一些主要人物,如 Grady Booch 和 Bertrand Meyer),以及 Laurence Tratt 在 2022 年的一篇文章(他直接参与了 UML 的标准化)。
这些文章都值得一读,但它们都有一个在本质上相似的解释:UML 变得太复杂了(例如,UML 2.2 文档长达 1000 多页,UML 变得与繁重且经常浪费时间的前期工作联系在了一起。)
在这一点上,我们谈论的是一种已经有近 30 年历史的方法论,一种支持者和批评者都认为它基本上已经死了的方法论。
然而,正如 2014 年的一项研究所表明的那样——与研究人员自己的期望相反——他们所服务的大多数开发人员和软件架构师都在创建“至少包含一些 UML 元素”的草图和图表。研究人员指出,“其中大多数都是非正式的”,但这仍然是一种令人惊讶的超越死亡的强大生命力。
偶尔,这个话题也会直接出现,我们可以看看人们是如何谈论现代 UML 的。例如,在这个 HackerNews 线程中,一个用户询问学习 UML 是否值得他们花时间,虽然大多数用户都认为 UML 本身是无用的,但也有用户建议学习一些 UML 技术(其中最主要的是时序图)。
一位用户甚至写道,“清晰的时序图所带来的回报,抵得上在大学里学习所有其他东西所带来的痛苦和无聊”,这是我见过的一个相当强烈的建议了。Mark Watson 提出了一个更强烈的建议,他与人合著了一本关于 UML 的书,但现在他说“时序图是我现在仍在使用的唯一类型的图了。”
我们可以把时序图的生存能力追溯到 UML 的起源。在 UML 的全盛时期,Martin Fowler 为 UML 确定了三个用例:草图(sketching)、蓝图(blueprinting)和编程(programming)。
按照 Hillell Wayne 的说法,编程用例的消亡是因为“即使是 UML 的大多数支持者也认为这是一个糟糕的想法。”蓝图用例实际上是看起来最强大的一个,但也消亡了,是因为该用例与 Rational Software 和 CASE 工具捆绑在了一起——这两个工具都消亡了,也就带走了 UML。
第一个用例——草图——幸存了下来,但 Wayne 说,它“漂移到了多种相互难以理解的方言中”。Tratt 对此表示赞同,他写道,事后看来,UML 在 2000 年“作为软件草图的媒介”达到了顶峰。
绘制草图的媒介是一个比 UML 支持者所想象的还要谦逊得多的愿景,但我们不应该低估剩下的东西——尤其是当涉及到时序图时。
时序图之所以能够幸存下来,不仅仅是因为它们是一堆烂图中的佼佼者,还因为它们真的很有用。正如我在上面所写的那样,时序图的要点是,你可以使用它们来轻松地映射和可视化系统中的动态消息流。
消息流可能会变得非常复杂,但时序图提供了两个主要组件来创建图的主干:
生命线(Lifelines),表示对象及对象之间的处理过程。
消息(Messages),表示随着时间推移而交换的信息。
基本组件必须要简单,因为时序图旨在表示一个运行中的系统,这意味着所表示的组件将同时、按顺序且并行地运行。一个好的时序图显示了流、对象之间交换的信息以及在生命线“死亡”之前所执行的功能。
时序图的主要用例有:
在构建系统之前,先绘制和设计系统应该运行方式。
记录新系统的需求。
分解并理解现有的(通常是遗留的)系统。
时序图不能(也不应该)捕获整个系统,因此在这些用例中,最好的方法是使用它们来可视化系统的使用方式,绘制特定流程的逻辑流程图,或绘制服务的功能图。
当你需要文档化系统的不同部分以及这些部分之间的各种交互方式时,时序图确实很有用。例如,当你试图在特定系统中为算法建模时,时序图就不那么好用了。如果你做得太精细,太详细,时序图就会变得过于麻烦而不值得。但是,当你用它们来绘制不同的“黑盒子”,并展示它们是如何相互交互的话,它们就会非常有用。
但和其他图一样,时序图的成功取决于你的制作水平。然而,它们的质量并不取决于纯粹的努力,而是需要一种谨慎、深思熟虑的方法,这种方法从核心流程开始,向外扩展到边缘案例。
你想要制作时序图的原因可能有很多,但无论灵感是什么,制作时序图并解决原始问题的最佳方法是由内而外,找出解决问题的方法。
当你坐下来创建时序图时,可能很容易从边缘案例开始,因为边缘案例通常是最复杂、最需要澄清的。
通常,激发你创建时序设计的可能就是一个边缘案例(如果你正在创建时序图来支持架构设计),或者是一个已经存在的、已经很麻烦的边缘案例(如果你正在创建一个时序图来更好地理解遗留软件)。但是,即使你的主要目标是澄清这些边缘案例,如果你首先从合适的路径开始,你也会创建一个更好的时序图。
在你开始时,确定一条合适的路径——这是信息从头到尾流动的理想方式。一旦绘制了这个核心时序,就可以向外扩展到其他路由和一些更不频繁的消息流。
例如,在使用银行应用程序登录的示例中,最好从合适的路径开始——客户请求访问权限,银行授予访问权限。从这个核心流程开始,可以确保当你仔细思考并记录不同的流程和边缘案例时,该合适的路径仍然是你的锚点。
在此基础上,你可以为幸福之路增添更多的复杂性。在下面的示例中,我们添加了更多的组件,包括身份验证服务和数据库,但该核心的合适路径仍然是中心。
从合适的路径开始可以提供清晰性,确保当你转移到边缘情况时,你知道时序应该如何运行,并且知道为什么用户可能会遇到边缘情况。构建和退出合适路径也是避免最终的图过于复杂的最佳方法。
时序图最常见的失效模式是过于复杂。(这也是大多数图表的失效模式,正如我在一篇关于流程图的文章中所写的那样)。
这里最值得提到的一个人是是 Martin Fowler,他(大约 20 年前)曾写道,绘制图表的主要价值在于沟通。“有效的沟通,”Fowler 写道,“意味着选择重要的事情而忽略不太重要的事情。”
忽略是最困难的部分。因为制图的目的是为了交流,因此有必要去掉一些信息以澄清其他信息。Fowler 提醒我们,“代码是全面信息的最佳来源”,因此图在本质上不应该是全面的(这正是代码的作用所在)。Fowler 说得很好,他写道“全面性是可理解性的敌人。”
你可以在下面的时序图中看到这一点,一位开发人员在 PR 中引用了该时序图,要求团队“考虑从图中提取出不太重要的信息,以便阅读的开发人员能够专注于重要的想法。”
Thomas Beale 在他关于 UML 之死的文章中写道,UML 变得过于复杂的主要原因是创建者试图“定义一个单一的元模型”,该模型可以提供十几种图表类型所需的所有元素。Beale 认为,“事实上,每种类型的图表都代表了一个特定的概念空间,它需要自己的特定模型。”
UML 本身已经消亡了,部分原因是它增加了复杂性,而不是提供了清晰性。今天记住这一点很有用,因为就像 UML 的消亡一样,如果任何给定的时序图变得过于复杂的话,它也会失败。
如果说前一个问题是过于全面和过于宽泛的结果,那么下一个问题则是过于详细和过于狭隘的结果。
在 Alex Bell 关于 UML 狂热的文章中,他描述的众多“毒株”之一是“Gnat’s eyebrow fever”,这是最有可能困扰时序图的问题之一。他将这种狂热描述为“非常强烈地想要创建极其详细的 UML 图”,并认为这种狂热源于这样一种信念,即绘制细粒度的细节图“为生成的代码增加了更加正确的可能性”
然而,实现是关键所在,因此,如果你正在构建一个时序图,以便更好地告知设计需求,那么在这个过程中,停止绘制图并开始编码才是更有效的。
也就是说,这个原则扩展到了用例之外。例如,如果你正在构建一个时序图来传达文档中的流程,那么对读者来说,可视化的全局大图比深入挖掘细节更有用。这并不是说细节不重要,而是太多的细节会削弱看全局时序的能力(这是时序图的主要目标)。
同样的原理也适用于分析和记录遗留代码——细节在于代码本身,因此时序图只有在你使用它来可视化全局时才有用。
本文的重点并不是纯粹出于对历史的好奇才来研究时序图的。时序图不仅是 UML 的产物,而且是强调严格设计和规划的软件设计思维的产物。
Fowler 解释说,图表和“重量级”流程之间的关联是图表绘制不好的结果,而不是图表制作本身的结果。本文中的建议旨在帮助大家创建更好的时序图,但在这个过程中,希望能帮助大家更好地了解在设计和文档库中拥有绘图技能所带来的可能性。
最好的工作来自于设计和编码之间的循环——创建一个前期设计,基于设计进行编码,并将从编码工作中所学到的东西反馈到设计中。如果一个图表能帮助你理解一个时序,那么正如 Fowler 所写道的那样,把它扔掉是“完全合理的”。(然而,“扔掉它”并不一定意味着永远地删除它;如果你想仔细回顾以前的工作,把它放在一边通常是有帮助的,这样你之后就可以再召回它)。
Jacobson 在他关于 UML 之死的文章中强调,“重点是,每一次 sprint 都要以架构思维为先导。”特别是使用时序图时,你可以更好地理解手头上的流程,从而使构建或改进组件变得更加容易。
原文链接:
https://www.mermaidchart.com/blog/posts/sequence-diagrams-the-good-thing-uml-brought-to-software-development
声明:本文为 InfoQ 翻译,未经许可禁止转载。
Python吞噬世界,GPT吞噬Python!ChatGPT 上线最强应用:分析数据、生成代码都精通
阿里转岗先离职:清空司龄裁员不给钱?马斯克作死推特,对手小扎社交平台喜获3000万用户;美国或限制中国用户使用美云服务|Q资讯
微信扫码关注该文公众号作者