用 UML 来描述领域模型吧
UML 统一建模语言的目的是在于提出一种独立于程序实现之外的描述方式,以可视化的方式对对象进行建模。可以用于对产品的描述、文档的编制等。同时因为其使用了严格的图形语意的规范,所以可以保证所有模型提供的信息方式是一致的,便于直接理解和阅读。
而对于复杂系统来说,通过对不同层级的系统进行建模。就可以将整个系统的模型描述清晰了。
UML 建模分为结构图( structure diagrams )和行为图(behavior diagrams)两大类。
结构图:
结构图主要是为了描述一个系统中的静态结构关系,包含:
类图
对象图
部署图
包图
复合结构图
组件图
从不同图的名称可以看出,不同图主要是在系统中的层级不一样,即图中元素的大小不一样。
行为图
而行为图是描述一个系统中的对象是如何随时间而变化的动态序列,包含:
用例图
序列图
协作图
状态图
活动图
领域模型
领域建模是为了体现现实世界中的实际概念,而这个实体并非直接等于 Java 等面向对象语言中的对象,所以领域模型在 UML 中可以用一组没有操作的类图来描述。
所以在本文中主要针对领域建模时所需要用的类图来介绍。
类图
类图主要是用来描述面向对象程序中的类、接口以及他们之间的静态结构,而我们也借用这种关系勒描述领域模型。
一张类图主要由两部分组成:类、关系。
类
一般来说我们用一个方形类表示类,可以简单记为:
也可以通过书名号类表示类的类型,但一般用得最多的是接口,例如:
如果需要描述类的细节内容,则可以在类上进行属性以及方法的描述,例如:
属性以"访问权限 属性名称: 属性类型"的形式进行定义。对于访问权限的表述方式为:
+:public
-:private
#:protected
方法以“访问权限 方法名称(入参): 返回类型”的形式进行定义。
而对于领域模型来说,如果不关心属性、方法的具体细节,则可以省略访问权限、属性类型、入参等信息,仅保留名称进行描述,
关系
UML 类图中,类之间关系有如下: 泛化(Generalization), 实现(Realization),组合(Composition),聚合(Aggregation),关联(Association),依赖(Dependency)。
关系间的强弱顺序为:泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖。
接下来我们按关系的强弱顺序进行描述:
1. 泛化(Generalization)
泛化描述继承关系的,用于描述一般与特殊关系。对应到 Java 中可以参考父类与子类的关系,其中子类将继承父类的全部特征与方法,且还能在进行追加或重写方法。
举例:自营商品是商品的一种泛化。
代码实现:继承父类
表示方式:空心箭头的实线,其中箭头指向父类。
如图:
2. 实现(Realization)
实现是用于描述接口和类之间的关系的,特指类实现了接口。
举例:订单实现了可支付接口。
代码实现:实现接口
表示方式:空心箭头的虚线,其中箭头指向接口。
如图:
3. 组合(Composition)
组合表示整体与部分的关系,当其中的部分无法脱离开整体单独存在的时候,就是组合关系。而整个部分中,部分的生命周期与整体的生命周期一致,即整体负责部分的生命周期。例如当公司解散了之后部分无法单独存在。
举例:订单和订单明细是整体和部分的关系;公司和部分是整体和部分的关系。
表示方式:一端为实心棱形、一端为普通箭头,其中箭头指向部分、棱形指向整体。
如图:
4. 聚合(Aggregation)
聚合也是表示整体与部分的概念,但聚合中的部分是可以脱离整体单独存在的。
举例:车和轮胎是整体和部分的关系,当轮胎单独取下后可以存在甚至可以售卖。
表示方式:一端为空心棱形、一端为普通箭头,其中箭头指向部分、棱形指向整体。
如图:
注意:组合和聚合也可以都看成是“聚合”,其中聚合称为“基本聚合”,组合称为“组合聚合”,所以都用棱形来表示。
5. 关联(Association)
关键是描述类中通过某种方式可以知道其他类的属性与方法。例如:航线与飞机、公路与自行车。
举例:一个航线上可能被多个飞机飞行,飞机也可以在多条航线上飞行。公路上可以同时行驶多个自行车,而自行车也可以在多个公路上骑行。上述两个例子就都是多对多的关联。
代码实现:成员变量
表示方式:带普通箭头的实线,指向拥有者。如果是双向关联(多对多),则可以省略箭头。
如图:
特别的,如果一个人类有自己的关联,则可以由自己指向自己:
6. 依赖(Dependency)
当一个类需要另一个类的帮助时就存在依赖关系。在代码中可能是入参、局部变量、部分方法的返回值等。
举例:程序员依赖电脑。
表示方式:带普通箭头的虚线,指向被使用者。一般来说不应存在双向依赖。
如图:
关系数量
对于关系,因为是描述的类与类之间的关系,所以会存在一个类与多个类的关系。如果一方的数量是固定的话,则直接标记一个数字就可以了,如果一方的数量是范围的话就可以用"下限..上限"的方式类进行描述,例如:“1..5”。其中“*”号表示 0 个或多个。用几个例子来说明:
0..1 表示 0 个或 1 个
1 表示 1 个
0..* 表示 0 个或多个
* 表示 0 个或多个
1..* 表示 1 个或多个
5..15 表示 5 到 15 个
特别的不写默认为 1 个
最后
常用的 UML 工具由 Visio、Process On,但是我强烈建议用飞书文档中的流程图,是真的好用,本文的图都是用飞书制作。
UML 类图在用多了之后就能记下来其中的图形与形状的映射关系了,可以按照:
箭头是否特殊三角
末端是否有棱形、以及棱形颜色
线是否为实体
这三项来排序,箭头三角的优先,末端有棱形的优先且颜色深的优先,线则是实体的优先。这样的关系在对应上“泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖”的关系紧密顺序会好记一点。
版权声明: 本文为 InfoQ 作者【蜜糖的代码注释】的原创文章。
原文链接:【http://xie.infoq.cn/article/9d57e2930334d1c9f6275fbbc】。文章转载请联系作者。
评论