仓库源文

.. Kenneth Lee 版权所有 2016-2020

:Authors: Kenneth Lee :Version: 1.0

Use Case图有什么用?


第一部分:问题

这篇博客我分上中下三个部分写。第一部分我先请读者做一个思考,到底Use Case图有什 么用?我在各种交流,乃至招聘中,都问过这个问题。大部分的回答都是:Use Case图的 作用是列出所有的使用场景(Use Case)。

如果Use Case的作用是列出所有的使用场景,它比起“需求(场景)列表”好在哪里?我们 把系统分层变成图,把类关系画成图,是因为图比文字(或者列表)更清晰表达了层级, 组件之间的关系,如果Use Case图的作用仅仅是重新展示一个个的需求(或者说需求的主 要场景),那么,Use Case图是用来解决什么问题的?

第二部分:回答

讨论区中Tiger的回答像教科书一样精准。的确,Use Case图的目的不是为了说明Use Case ,而是为了说明系统的边界。所以Use Case图和需求列表完全不是一个东西。有心的读者 可能注意到了,无论是结构化建模方法还是面向对象建模方法,他们首先解决的问题都是 系统的边界:到底什么在设计的范围,什么不在设计范围内。

举个例子,我们预期做一个数据库,什么是这个数据的功能呢?按结构化建模方法,系统 建模的上下文图如下:

    .. figure:: _static/usecase图1.jpg

中间的“数据库”处理,就是系统的边界。同样的概念,放到按完全不同理念建模的面向对 象建模,得到的模型是这样的:

    .. figure:: _static/usecase图2.jpg

这两个图的表现形式看来完全不同,但它们起的作用是完全一样的。它们是从不同的角度 来定义要做的这个产品的边界在什么地方。什么“算”我们要实现的范围,什么不算要实现 的范围。这两个图都没有表达比如:访问数据库的Client,算不算数据库的范围;或者提 供数据库所运行的Infrastructure环境,是不是交付的一部分。这些东西才是需求列表一 类工具描绘的对象,CD和UCD描述的是,当我们说“数据库”这个概念的时候,到底指向什么 范围,以便让其他细节依附上去。它是定义架子的,不是定义精确细节的。

很多人把CD和UCD当作了对程序的精确反映了,所以构造了复杂无比的CD和UCD,又因为放 不下那么多内容,然后迫不得已进行了部分的精简,最后反而导致了描述的不精准(架构 的精准和设计的精准不是一回事的)。这种CD和UCD毫无意义。一副图的表达能力,20个对 象,基本上就是描述的上限了,多了就已经没有意义了。你用图去复原需求列表或者设计 的实际对象,还不如直接去描述需求列表和进行编码。在我们这个例子中,表达“数据库 Client是否包含在设计范围中”这一点本身,不需要通过图来表述,因为它并非数据处理的 核心(可能是工作的核心,但不是整个数据处理的核心)所以在整体概念中表述中没有非 常“必要”的作用,换句话说,在后面的展开中,很容易就澄清这一点了,而且毫不影响对 系统范围的理解,这个定义就不会在图中表述。而部分更无知的所谓架构师,把诸如“关键 字”等概念放到这一级建模的输入输出中(他们会说:“没有关键字怎么可以查询到记录呢 ?”——按他们这个理论,他们还不如问“画个图怎么就可以运行呢?”),就完全是不着边际 了。

第三部分:再理解构架

我举这个例子,是要再次请读者面对一个问题:很多人做架构师入不了门,始终无法突破 这个障碍:架构师不是程序的开发者,他在设计层面不能代替开发者。当一个架构师画下 一副Use Case图,或者一副类图,他的目的不是要告诉下一级的设计师,具体应该如何设 计这个东西,而是要告诉下一级的设计师:我将会用这些概念作为逻辑进入我这个层面的 设计,你们必须为我圆这些概念的慌。由于这些慌不一定全部都可以圆,所以构架师必须 给他的概念定义留有余地,而且容易理解。所以他才常常用图来取代文字描述,因为图形 更有利于表达那种“一眼”就能看出关系的概念,并留下足够的修改余地。架构师做这种定 义必须严格遵循两个原则:

第一,图是为了让人基本来一眼就能看出概念来,如果它的逻辑比文字还难以组织,这个 图就没有意义了

第二,架构师不能取代设计师进行细节设计,所以,在必然能够实现的设计上,架构师不 能着墨

我看过非常大型的产品的绝密级别的DFD图,里面包含几十副图,每幅图上有近百个加工, 我跟他们说,你这个设计根本就不需要加密,你这个东西就算拿出来也没有什么人能看懂 。这样的文档早就失去进行架构控制的自由度了,写出来就是走过场。纯粹浪费时间。

道德经说,高以下为基,贵以贱为本。为什么?高高在上的人,无论他多么亲民,他永远 都不可能和底层一样生活。领导者如果变成底层实施者,他就不是领导者了。所以,作为 大型团队的领导者,你永远没有机会了解每个模块如何设计。做服务器的架构师,你敢说 你懂SAS,SATA,SR-IOV,NetMAP,PCIE,FIO-platform,BCD,ACPI的工作原理?你是工 作每个子系统的工程师的结果上的,但你和你的团队在这个过程中都需要成长,所以用于 你们互相对齐的模型就不可以复杂,而且互相一定很容易向对方传递模型的破绽。所以, 定义模型,必须定义得简单明了,然后双方在不断的深入设计中(架构师基于模型“证明” 需求的可实现性,子系统工程师基于技术推演“证明”概念的可实现性),调整这个模型。 如果你一开始就把模型压死了(进行具体设计),这件事就毁了。我们看到很多所谓的架 构设计,到实施的时候被实现的工程师如弃敝履,原因就在这个地方。

拿数据中心的组网为例,你考虑用一般的策略,Docker Image间决定用VETH组网,VM间通 过OVS做交换,OVS之外再接物理交换机。你用这个逻辑完成你这一层的基本设计,但你向 下设计,就会发现这个模型你用不了任何硬件加速(比如SR-IOV)。然后你就需要调整你 的组网为从Docker这一层就开始对外出SR-IOV的VF接口,然后用片内交换机来做交换,然 后再用Tor交换机来做下一层的交换。然后你的团队(在设计后)会继续给你反馈,如果按 这个组网,节点间的时延会上升5个ms,你的图就必须继续更改。这种更改中,你会发现, 对于什么叫Docker,什么叫片内交换机,什么叫Tor交换机,这些概念是基本上不变的。架 构师必须始终控制这个基础的概念空间,才有可能控制整个技术讨论和决策。而Use Case Diagram,就是第一层的概念定义。架构师控制的整套UML模型或者DFD模型,都是控制概念 空间,而不是设计本身。

说远一点,说说中国现在的计算机教育,我看到很多从业人员写的各种设计,有一个小学 语文就应该解决的问题都没有解决:就是保证自己知道自己写下来的每行字,都有自己知 道的主语。比如这样的初始化流程:

  1. 先发一个信号i给ABC

  2. 返回信号j给DEF

  3. DEF开始重启动

  4. 然后ABC开始重启动

……

拜托,谁发一个信号i给ABC啊?谁返回信号j给DEF啊。“然后”?“然”是什么啊?是什么之 后啊?我实在想不明白这些人是怎么本科乃至研究生毕业的。所以,这篇东西的最后,算 是给读书的学生一点建议吧:请把你们的基本语文学好一点。您这个问题搞不定,你就很 难理解架构师的意思,你就无法参与大型软件开发——当然,也有公司貌似可以接受这样的 工程师。这个我下一篇讨论。