Thinking in uml 03 uml核心元素(三)
四.业务实体
业务实体是类的一种版型,特别用于在业务建模阶段建立领域模型。如果说参与者和用例描述了我们在问题领域中达到什么样的目标,那么业务实体就描述了我们使用什么来达到业务目标以及通过什么来记录这个业务目标。
如何理解业务实体?
(1)业务实体来自现实世界,在建模的问题领域里一定能够找到与它相对应的事物,并且这个事物是参与者在完成其业务目标的过程中使用到的或创建出来;
(2)业务实体必须至少被一个业务场景使用或创建,对业务场景没有贡献的事物,即使是客观存在的,也不应该为它建模;
(3)业务实体作为类的一个版型,具有对象的所有性质,包括属性和方法,同时也具有对象的独立性,即业务实体只应当包含它本身固有的特性,而不能包含外界如何使用它的信息。
1.业务实体属性
属性是用来保存业务实体特征的一个记录,业务实体的属性集合决定了它的唯一性。
在建模的时候是否需要把所有的属性都列举出来?不需要,在特定场景下,只需要关心与这个场景直接关联的属性。
很多时候属性并不是一个简单得不可再分的概念,属性本身很可能也是一个复杂的业务对象。一般来说,如果只有一个对象可以直接使用这个属性,或者只能通过对象才能访问这个属性,就应当作为一个属性存在;否则就应当把它单独建模成一个业务实体。例如,账户和定期。如果是招行的一卡通,只有一个账号,定期没有单独账号,更没有存折,对定期的所有操作必须通过一卡通账号进行,这种情况下,不论定期有多复杂的属性,它也只应作为一卡通账号的属性存在。而在其他银行,办理定期会单独开立一个账号,甚至有一个存单,客户可以直接处理这个定期账号,这种情况下,就应当单独将它建模成为一个业务实体。
2.业务实体方法
方法就是外部能够使用这个业务实体的全部信息。
同样的,在建模的时候,只需要关心那些与这个场景有直接关系的那些方法。
3.获取业务实体
步骤一:建立业务用例场景。业务用例场景是参与者实现其业务目标的过程描述,例如描述一个寄信人到邮件寄信的场景:寄信人到达邮局,购买信封,将信装入信封,写上地址,称重,计算邮资,购买邮票,贴上邮票,邮寄信件,拿走回执;
步骤二:从场景中逐个分析动词后的名词,它们就是业务实体的备选对象。例如:邮局、信、信封、地址、邮资、邮票、信件、回执等。根据对象是否对业务目标有贡献进行筛选:例如邮局是一个场所,是寄信的一个约束,或者是前置条件,对业务目标没有直接的贡献。
步骤三:分析这些业务实体之间的关系,并决定哪些单独建模,哪些应当作为属性。例如,地址和邮票都在信封上,其中地址只有信封能够承载,并且只能通过信封阅读地址,所以地址应该作为信封的一个属性,而邮票虽然也在信封上,但寄信人可以对邮票单独处理,比如在购买时邮票还没有在信封上,所以邮票应该单独建模。再比如,邮资实际上等价于邮票的面额,所以邮资可以被邮票的面额属性代替,并不需要为其建模。
最后业务实体包括:信、信封、邮票、信件、回执。
五.包
包是一种容器,如同文件夹一样,它将某些信息分类,形成逻辑单元。使用包的目的是为了整合复杂的信息,某些语义上相关或者某方面具有相同点的信息都可以分包。
分包的一些指导性原则:
(1)高内聚性质
如果将元素分为三个包A、B、C,那么被分入同一个包中的那些元素应当是相互关系紧密,甚至不可分割的。同时这些元素又具有某些相同的性质,使得包可以抽象出一些接口来代表包内事物与包外的事物交互,以避免包外的事物频繁地直接访问包内元素。
(2)包间无依赖或松耦合
最理想的情况下,修改任意包的元素,不会对其他包内的内容产生影响。
(3)包间依赖关系不会被传递
实际情况难以做到完全解除依赖关系,那么至少应当保证包之间的依赖关系不会被传递。例如B依赖于A,C依赖于B,当A修改导致B要做出修改时,C不会受到影响。
(4)尽量避免双向依赖和循环依赖
双向:如果A依赖于B,而B又依赖于A;循环:如果A依赖于B,B又依赖于C,而C又依赖于A。