DDD领域驱动设计批评文集
做强化自测题获得“软件方法建模师”称号
《软件方法》各章合集
8.2 建模步骤C-1 识别类和属性
8.2.2 三种分析类
8.2.2.6 自测题
扫码或访问http://www.umlchina.com/book/quiz8_2_2.html完成在线测试,做到全对以获得答案。
1. [单选]
方法学家马宝国老师在推行一种“面向浑元形意太极”的分析方法,按照本书的知识点,看到这个名字,我们最应该想到的是:
A) 你家老公会劈砖,小哥会打那太极拳
B) 马老师的建模方法是伪创新
C) 马老师的方法假设系统由“浑元形意太极”构成
D) 我左手一式太极拳,右手一剑刺身前
2. [单选]
为什么面向对象分析设计方法比面向过程好?
A) 面向对象更适合人脑去把握系统的复杂性。
B) 面向对象和需求的映射更直接。
C) 面向对象方法更容易掌握。
D) 面向对象更符合计算机的底层。
3. [单选]
铁路售票处,售票员使用售票系统来售票,在用例进行过程中,系统需要不断向旅客反馈车次、车票和价格信息,系统还需要和银行系统交互。"售票"用例的分析序列图中,会出现_____个边界类,_____个控制类,_____个实体类。
A) 1,2,3
B) 3,1,2
C) 不定,1,3
D) 3,1,不定
E) 3,2,3
F) 3,1,3
G) 不定,1,不定
H) 3,3,3
4. [多选]
关于边界类、控制类和实体类,以下说法正确的有:
A) 来源于Grady Booch对系统的分析类的构思,不属于UML规范的一部分。
B) 实际上就是MVC架构模式中的V、C和M。
C) 这三种类可以映射到任何实现架构,包括MVP、MVVM、六边形、洋葱型……
D) 如果所用建模工具没有提供边界类、控制类和实体类的图标,可以用文本构造型代替或者在类的命名上区分。
8.2.3 提炼类和属性
8.2.3.1 从需求规约之外的其他素材提炼
建模类及类之间的关系,可能在软件开发的分析工作流之前就已经发生了。
第7章“需求启发”中就提到,我们在研究资料的时候,可以通过画类图来整理领域的概念。整理领域概念时,有时还可以加上状态机图。即使不是为了开发软件,也可以通过这些手段来整理领域知识,帮助我们更快地理解和掌握领域知识。
以刘慈欣的《三体III:死神永生》中的片段为例,原文如下,我们把其中值得提炼的概念标红:
******
宇宙的熵在升高,有序度在降低,像平衡鹏那无边无际的黑翅膀,向存在的一切压下来,压下来。可是低熵体不一样,低熵体的熵还在降低,有序度还在上升,像漆黑海面上升起的磷火,这就是意义,最高层的意义,比乐趣的意义层次要高。要维持这种意义,低熵体就必须存在和延续。
至于这意义之塔的更高端,不要去想,想也想不出什么来,还有危险,更不用说意义之塔的塔顶了,可能根本没有塔顶。
回到坐标上来,空间中有许多坐标在穿行,如同母世界的天空中飞翔的矩阵虫。坐标拾取由主核进行,主核吞下空间中弥散的所有信息,中膜的、长膜的和轻膜的,也许有一天还能吞下短膜的。主核记着所有星星的位置,把信息以点阵方式与各种组合的位置模式进行匹配,识别出其中的坐标。据说,主核可以匹配五亿时间颗粒前的位置模式,歌者没有试过,没有意义。在那个遥远的时代,宇宙中的低熵群落比较稀疏,也还都没有进化出隐藏基因和清理基因。而现在——
藏好自己,做好清理。
但所有坐标中,只有一部分是有诚意的。相信没有诚意的坐标常常意味着清理空旷的世界,这样做浪费精力,还有一点点害处,因为这些空世界以后还可能用得着。无诚意坐标的发送者真是不可理喻,它们会得到报应的。
******
根据以上描述,可以画出如图8-27的类图来整理其中的领域知识。整理后,可以看出各个概念之间的关系,还可以看出,领域知识可以分为4个部分。
图8-27 用类图整理《三体III:死神永生》中的片段
图8-27可以称为“宇宙的领域模型”。这个模型可能和信息系统没有关系,因此不能称为“宇宙的核心域模型”或“宇宙的分析模型”。
如果某个信息系统“三体游戏”要封装图8-27的领域知识,那么图8-27可以称为“三体游戏的核心域模型”或“三体游戏的分析模型”,但不适合称为“三体游戏的领域模型”,因为“三体游戏”中封装了核心域和非核心域的知识。
从上面例子可以看出来,对于以上提到的几个用语,本书是按以下定义使用的:
领域模型:描述某个领域中的概念及概念之间关系的模型。
分析模型:从核心域视角描述的信息系统的模型。
核心域模型:等同于分析模型。
它们之间的关系如图8-28。
图8-28 领域模型和分析模型
模型可以用各种表示形式来表示,相应的形式可以叫“领域类图”、“领域ER图”、“分析类图”、“分析状态机图”、“分析类文档”、“分析状态机文档”……。
我们可以从各种素材中提炼某个领域的类和属性,不过这些类只能叫领域类,不一定是合适的分析类。到底哪些领域类会成为目标系统的分析类,需要从目标系统的需求模型(如果用本书上册的方法表示,就是系统用例规约)来判断该系统是否需要这个类。
没有需求规约,目标系统的边界以及应该承担的责任没有理清楚,那么,提炼得到的类到底是不是目标系统将来需要维护的概念,是没法判断的。也就是说,虽然在很多时间点、从很多素材都可以提炼类,让我们在确定分析类时,省去了许多思考,但分析模型的最终依据只能是需求模型。
当然,如果你脑子里对于系统该干什么不该干什么清清楚楚,只不过没写出来,那也算是有需求模型了——不过你得确定你真的懂,而不是拿这个当遮羞布。
如果按照本书所采用的面向对象建模、UML表示法和Ivar Jacoson三种类的分割,某个领域模型可能会包含某个系统的分析模型中的实体类部分,但不会包含边界类和控制类部分。
另外,在用类图表达领域模型时,我们只使用泛化、关联等静态关系,不使用动态的依赖关系,也不使用序列图来表达类之间的协作,因为这些内容在相关的信息系统运行时才会出现,而此时我们并没有在构思或建造信息系统。
★注意,刚才说的序列图和第4章的业务序列图的区别,也可以参考图8-25。
例如,图8-27中,“主核”和“信息”、“位置模式”以及“坐标”之间是关联关系。这是合理的,因为宇宙系统能把所有关系都记录下来,包括哪个坐标是由哪个主核识别出来的——当然,也包括导致太阳系被降成二维的那几次和三体世界的通信。
但是,如果我们开发一个信息系统“三体游戏”,即使游戏中有“主核识别坐标”的内容,系统未必要记录哪个坐标是由哪个主核识别出来的。此时,“主核”和“信息”、“位置模式”以及“坐标”之间不存在关联关系,只存在动态的依赖关系。某种协作方式(当然可以有其他协作方式)下的类图和序列图可能如图8-29。
图8-29 某种协作方式下的类图和序列图
有些书籍和文章作者,对软件开发的工作流没有清晰的概念,把所有用“业务语言”表达的模型,包括组织流程,系统需求规约等,通通叫作“领域模型”。这是不正确的,我们在阅读时要注意分辨。
8.2.3.2 从需求规约提炼
这是提炼类最严格的依据了。
阅读用例规约的基本路径、扩展路径、字段列表和业务规则部分(即所谓“功能需求”部分),针对表示名词或事件的词汇,逐个思考,这是不是系统要记住的核心域概念?如果是,那么它是类,还是某个类的属性?如图8-30。
图8-30 从用例规约识别类和属性
关于“系统要记住的”概念,可以这样思考,系统需要懂得哪些信息,才能根据执行者的请求提供恰当的价值?
如果您有关系数据库建模的经验,也可以这样简单地思考:如果系统需要维护的信息都采用关系数据库来保存,那么数据库里应该会有哪些表?这样思考得到的表和实体类基本上是一一映射的。表对应类,列对应属性,行对应对象,关系对应关联。后面我们会讲到,类模型可以直接转换成关系数据库模型,不需要再花工作量做一遍关系数据库建模。
如果关系数据库建模技能掌握得好,得到的数据模型符合1NF、2NF和3NF,那么用关系数据库建模的思考方式得到的类图极有可能也是合格的。反过来,也有理由怀疑,自诩关系数据库建模能力强的人,如果类建模做得乱七八糟,估计也有吹牛的成分。
当然,我们画类图的目的是整理核心域概念和逻辑,将来映射关系数据库只是顺带的便利。面向对象和关系数据库(或任何的具体存储方式)没有必然的绑定关系。任何系统都可以用面向对象的方式来构造,不管它用什么方式来存储对象。
以电梯为例。我们把为乘客提供电梯服务所需要的所有软硬部件看作一个整体,称为“电梯系统”。
乘客在发出某次召唤之前,电梯系统要懂得各部电梯当前运行方向、当前所处楼层、待去往的目标楼层集合以及楼层的结构,才能够合理应对乘客的召唤。这些可以看作系统要记住的信息。
乘客姓名、乘客召唤电梯的时间、电梯曾经去过的楼层等,系统则不需要知道。
画出类图如图8-31。
图8-31 电梯系统可能需要的实体类
这些信息不一定需要被“持久存储”。图8-31中的概念中,当前楼层、目标楼层、方向的信息一直在不断变化,甚至在电梯系统停止服务时会被清空,但不影响图8-31的类结构。
8.2.4 类和属性的命名
8.2.4.1 使用严谨的领域术语命名领域模型中的元素
领域模型中各个元素的名称尽量来自该领域的术语体系。
一个领域之所以能作为“领域”为人认知,必定会在发展过程中沉淀出一套日益完善和精确的术语体系。每个术语有其独特的、其他术语不能替代的含义。
例如物理学中的质量、重量、重力、引力、衰变、裂变、聚变……,各自有各自的含义,不是另一个概念可以取代的。
涉众习惯的用语不一定是严谨的领域术语
也许是出于自己的知识局限,或者出于字数少使用方便,涉众有时习惯于使用一些不严谨、感性的用语,这些用语不一定适合用来命名领域模型中的元素。
这些用语经常会用颜色、大小等感性认识来称呼领域概念。例如,货车司机可能会把一张单子称为“绿单”,因为单子的颜色是绿色的,但更精确的名称可能是“送货单”;购物时的“小票”,名称来源于面积较小(和面积更大的“发票”比较),更精确的名称可能是“收据”。
这些用语所依赖的信息,稳定性往往比真正的领域内涵要差。有关机构可以改变送货单的颜色,购物收据也可以变成面积比发票要大的大长条,“绿单”、“小票”等用语就不再合适了。即使已经形成了习惯不得不一直沿用下去,真实的情况和字面的意思已经大相径庭。
涉众喜欢用不严谨的用语,这是正常的。某类涉众的领域知识可能会很片面,对领域概念认识不深刻,怎么能寄望一个使用探探来交友的屌丝青年清楚社交六度空间理论呢?
第7章说到,涉众关注的是涉众利益,涉众没有资格也没有责任提供需求。同样,涉众也没有(或更没有)资格和责任提供分析。精确使用领域术语是建模人员的责任,不是涉众的责任。
同一领域概念,不同涉众可能会有不同的习惯用语
例如:老鼠-耗子、马铃薯-土豆、祖母-奶奶、宝贝-商品、购物-买东西。
如果怀疑两个用语描述的是同一个概念,可以这样问:有没有不是商品的宝贝?有没有不是宝贝的商品?如果回答都是否,就清除掉其中一个,否则,应该继续研究两个用语背后的真正含义,必要时在模型中表达其中差别。
如图8-32,左侧的几个概念中,经过审查,认为"宝贝"和"商品"、"顾客"和"客户"含义相同,去除其中一个;"用户"、"顾客"、"会员"含义有差别,在类图上更精细地表达。
图8-32 清理冗余的用语
当然,在和人类执行者交互的界面上,针对各自的习惯,依然可以使用不同用语如“宝贝”、“商品”称呼同一概念。
也可以对“同一概念不同涉众用语不同”这部分知识建模,以备在界面上使用,如图8-33。上面提到的“宝贝”、“商品”就成为了“用语”类的对象。
图8-33 建模“同一概念不同用语”
图8-33中所描述的类以及类之间的关系适用于各个领域,和某个特定领域并不相关,因此不要把这部分知识和特定领域的知识混在一起。假如建模成图8-34,就搞混了“是一个”和“有一个”的区别,又变成废话刷工作量了。在后面“识别类的关系”内容中会再详细讲述。
图8-34 “同一概念不同用语”的错误建模
领域专家
建模人员除了和各类涉众交流,还需要从领域专家那里获取严谨的领域知识和领域术语。
首先要提醒的是,“领域专家”这个词已经被严重污染。
很多人把“经验较多的涉众”当成了领域专家,例如跑运输多年的老司机,例如通过某社交软件约了几百人的老司机。但正如上文所述,这些涉众不一定是领域专家,他们也许能提供丰富的素材,但未必能严谨表达和深入思考。
领域专家要能够从研究学问的角度来看待他所在的领域。他应该有该领域比较扎实的基础知识,经常阅读该领域的最新文献,了解该领域当前研究进展。领域专家可能是该领域的“研究人员”,至少也是该领域的“科普人员”。
“研究人员”、“科普人员”加了引号的意思是他们不一定要有“教授”、“研究员”、“老师”等正式的职位,但至少满足上面所说的要求。当然,上面提到的货运老司机、社交老司机等涉众如果能深入研究自己所在领域的学问,也可以成为领域专家。
领域专家很可能并不是涉众(当然也可以是)。例如,为A公司开发供应链系统,建模人员可以向B高校研究供应链的学者请教领域知识。学者是领域专家,但他可能跟A公司没有关系,这个系统最终会是什么样子,也不涉及到他的特定利益,他并不是涉众。
如果有条件,建模人员可以和领域专家直接交流,借助领域专家的指点,尽快得到确实反映领域内涵的模型。如果没有条件直接交流,可以通过阅读领域专家的各种产出,间接获得帮助。
上文也提到,领域的术语体系是日益完善的。在熟练掌握领域现有术语体系的基础上,辅以严谨的建模技能(背后是一些数学思想),建模人员可以起到“反哺”的作用——帮助清理领域当前术语体系中存在的冗余和矛盾并改善。注意其前提条件:熟练掌握现有术语体系+严谨的建模技能,这不是随便就能达到的!
UMLChina公众号精选(20231208更新)按ABCD工作流分类