软件方法(下)第8章分析之分析类图—知识篇Part10-审查类和属性2

2022-10-31 17:05:56 浏览数 (1)

DDD领域驱动设计批评文集>>

《软件方法》强化自测题集>>

可到此处下载《软件方法》(下)目前公开的最新pdf版本:

http://www.umlchina.com/book/softmeth2.pdf

8.2.5.3 属性是否在本领域内可分解

如果属性再分解就得到另一个领域的概念,那么这个属性可以留在类中。如果属性可以继续分解成本领域的概念,那么可以考虑把这个属性独立出去变成另一个类。

如图8-83,"人员"的"称呼"属性的类型是String,相当于"人员"关联到String类。String属于基础语义领域,已经不属于"人员"所在的“人员管理”领域,那么"称呼"可以留在“人员”中作为属性存在。

图8-83 String可以留在类中

而"组织"还可以像右侧所示分解成“名称”、“办公地址”等,这些概念依然属于“人员管理”领域,所以可以考虑将“组织”分离为一个类,“人员”关联到“组织”。

图8-84 组织需要分离出来

注意以上的用词。我们只是说“再分解就得到另一个领域的概念”,并没有暗示这个另一个领域是什么,更没有暗示这个领域比核心域简单。任何领域,只要愿意深入研究,都是复杂的。

就拿“称呼”的类型String来说,String如果用.NET中的String类实现,这个类有157个操作,远远超过“人员管理”领域中某个类所拥有的操作数目。只不过String类如何构造是别人负责操心的事情,不是我们目标系统的建模人员操心的事情。

在分析工作流,我们只需要判断某个属性再分解就到了另一个领域,或者说类型是另一个领域的类。至于属性的类型具体是哪一个类,UML提供了一些原生类型,如果认为属性的类型刚好是这些类型之一,可以指定,否则可以先不指定,因为分析模型没有绑定到任何一个具体的编程语言和数据存储平台,而不同的编程语言和数据存储平台的类型体系还是有差别的。

在EA中,把类的语言设成none,在属性的类型选择中,就看到UML定义的原生类型,如图8-85。

图8-85 UML定义的原生类型

8.2.5.4 是否有多重性大于1的属性

如果某个属性经过了8.2.5.3 属性是否在本领域内可分解的检验,但该属性多重性大于1,即所谓多值属性。例如,人员有多个手机号。

这时可以:

(1)把“手机”属性留在“人员”类中,多重性设为多,如图8-86。

图8-86 把属性的多重性设为多

注意,只需要说明多重性为多,不要放上一个该属性的数组或List之类。人员有多个手机号,这是一个领域的知识;用编程语言如何实现多值属性,是另一个领域的知识。一旦混杂,又会导致批量刷工作量。

(2)更推荐的做法是,把该属性分离出去,如图8-87。

图8-87 分离多值属性

人员有多个手机号,背后往往是有原因的。虽然现在不关注,很可能以后就会关注。例如,有的手机号是私人用的,有的手机号是办公用的,如果需要关注这些知识,那么就需要从图8-87转成图8-88中的某一个,此时只需要添加关联或者在“手机”类添加一个属性。

图8-88 当需要关注更多的知识时,类图发生变化

当然,这也不是建模“人员有多个手机”的最好做法。后文我们介绍到人员相关的分析模式时,会详细描述如何建模这个领域。

以下做法是不好的:

(1)在“人员”类中放上多个属性“手机1”、“手机2”、“手机3”……,如图8-89。

图8-89 错误:放上多个属性

这样的做法相当于把抽象级别降到了对象级别,或者用关系数据库建模的说法,这是违反第一范式的。如果人员没有那么多手机号,某些属性就会出现空值;如果人员拥有手机号的数量大于预设的个数,就会放不下。

(2)只有一个“手机”属性,属性值里用逗号分隔各个电话号码。

如果这样的做法是好的,那不如更进一步。各个属性也不用分了,就一个字符串。还可以再进一步,类也不用分了,也串在一起……持久存储或网络传输时的序列化不就是这样干的吗?

根源就在于软件是人做的,人脑的容量和运行速度有限,否则就不用理得那么清楚了,直接对计算机下二进制指令不好吗?

8.2.5.5 属性是否对所有对象都有意义

如果通不过8.2.5.1 属性直接描述类的检验,那么类和属性放在一起是不合适的,但这只是必要条件,不是充分条件,即使通过了也未必合适。

如图8-90,人的姓名,人的▲▲(▲▲是男性特有的器官),人的〇〇(〇〇是女性特有的器官)好像都说得通,但如果问:是不是所有对象都应该有这个属性呢?得到的答案就不同了。

是不是有人有姓名——是。

是不是所有人都应该有姓名——是。

是不是有人有▲▲——是。

是不是所有人都应该有▲▲——不是,只有一部分人有。

是不是有人有〇〇——是。

是不是所有人都应该有〇〇——不是,只有一部分人有。

说明“人”发生了分裂,分裂成“男人”、“女人”两个子集(子类)。▲▲是男人的属性,〇〇是女人的属性。

图8-90 分解只属于部分对象的属性到子类

扫码或访问http://www.umlchina.com/book/quiz8_2_5.html完成在线测试,做到全对以获得答案。

1. [单选]以下符合“属性是否直接描述类”的是:

 A)

 B)

 C)

 D)

2. [多选]在符合某些条件时,这样建模是可以的,请把这些条件选上。

 A) 开发团队决定走敏捷精益的领域驱动架构设计路线。

 B) 手机只有一个摄像头。

 C) 摄像头只关注一个属性:像素。

 D) 用关系数据库来保存手机对象。

3. [单选]电子商务系统有一个类“商品”,“商品”有属性“名称”和“演示动画”。开发人员初步打算在实现时,“名称”的类型设为编程语言的String,“演示动画”的类型设为某个通用3D类库的“Animation”类。以下说法正确的是:

A 因为String比较简单,所以“名称”属性可以留在“商品”类内。

B 因为Animation比较复杂,所以“演示动画”属性应该分离出去变成关联。

C 因为String和Animation都比较复杂,所以两个属性都应该分离出去变成关联。

D 因为String和Animation都不属于核心域概念,所以两个属性都可以留在“商品”类内。

4. [单选]在某个系统中有一个“电子邮箱”类,它的对象用关系数据库存储,放在数据库的“电子邮箱”表中。“电子邮箱”表的部分行如下:

ID

地址

用户名

密码

SMTP

POP3

11259

zhangdaong@163.com

zhangdaong

alcohol150

smtp.163.com

pop.163.com

11260

luodafeng@vip.sina.com

luodafeng

fengjie123

smtp.vip.sina.com

pop3.vip.sina.com

11261

wanglihong@163.com

wanglihong

wipeshyn1

smtp.163.com

pop.163.com

……

作为一名学习了本部分内容的读者,看到这些行,应该想到的是:

A) 类和表的结构基本一致,类的属性相当于表的列。

B) 可能需要把“电子邮箱”的一些属性移到另一个类。

C) 密码不应该用明文存储。

D) 这样做不够敏捷,也不够DDD。

8.2.6 评价DDD话语中的“值对象”

在识别类的时候,有的建模人员受到DDD话语体系的影响,会着急去分辨哪个类是实体(Entity),哪个类是值对象(Value Object),这是没有必要的,而且很容易成为遮掩无能的遮羞布。

关于DDD话语中的“值对象”,可参见我写的《“值对象”是DDD的创新吗》一文,本书不再花大量篇幅阐述。

《“值对象”是DDD的创新吗》的要点:

(1)“值对象”类似概念不是Eric Evans发明的,也不是Eric Evans给起的名字。

(2)只需实事求是描述领域内涵,结果会自然而然显露出来,并不需要套上“实体”和“值对象”的概念。

(3)EricEvans以性能为理由来强调“值对象”的重要,不合适。

(4)“值对象”命名不严谨。

[202205升级知识讲解]23套UML EA和StarUML的建模示范视频-全程字幕

6月9-12晚网络软件需求设计方法学全程实例剖析公开课

5月26-29晚剔除“伪创新”的领域驱动设计-网络公开课

《软件方法》书中自测题-题目全文 分卷自测(1-8章)16套111题

《软件方法》强化自测题集110题

CTO也糊涂的常用术语:功能模块、业务架构、用户需求……[20210217更新]

如何选择UMLChina服务


0 人点赞