文章目录
领域模型
association vs attribute
association 用于实例之间关系,attribute则用于需要记住的信息
一般来说人们会比较实例的址而比较属性的值
value object更像是data type
ID
考虑这样的productId,由countryCode+manufacturaterCode+id组成,但是我觉得这样的情况应该视为逻辑编码,除了用来查询外不应当做唯一id使用,更加不能解析该id,因为countryCode有可能改变(换了国家),另外manufacturaterCode没有包含countryCode也是令人奇怪.
number attribute
一般来说涉及到数量的时候会有单位,典型的就是Money
示例
s:开始 r:精化
科目 | 制品 | 初始 | 细化 E1->En | 构造 C1-Cn | 移交 T1->Tn |
---|---|---|---|---|---|
业务建模 | 领域模型 | s | |||
需求 | 用例模型 | s | r | ||
设想 | s | r | |||
补充性规格说明 | s | r | |||
词汇表 | s | r | |||
设计 | 设计模型 | s | r | ||
软件架构文档 | s | ||||
数据模型 | s | r |
从理论的角度来看,理论与实践应当是一致的
从实践的角度来讲,实践与理论其实是不同的
概念分类列表
- 有形对象
CreditCard , Check- 事务
CashPayment , CreditPayment , CheckPayment- 其他外部的计算机或机电系统
CreditAuthorizationService- 抽象名词概念
- 机构组织
- 金融,工作,合同,法律事务等的记录
将概念类划分为子类的动机
- 子类有额外的有意义的属性
- 子类有额外的有意义的关联
- 子类概念操作,处理,反应或使用不同于其超类或其他子类,而这些方式是我们所关注的
- 子类概念表示了一个活动体(如动物,机器人),其行为与超类或者其他子类不同,而这些行为使我们所关注的.
简化继承树
abstract conceptual class
定义
如果类C的每个成员也必须是某个子类的成员,则类C被称为抽象概念类
准则
识别抽象类,在领域模型中使用斜体字标识抽象类的名称,或者使用{abstract}关键字标识
状态
准则
不要讲概念X的状态建模为X的子类,有两个办法可供选择
- 定义状态类层次结构,并将其与类X关联
- 在领域模型中忽略概念的状态,而在状态图中加以反映
继承
采用一种面向对象语言,通过创建类层次结构,软件子类继承超类的属性和操作定义.继承是使超类的特性适应于子类的软件机制,它支持对子类代码的重构,将其置入超类之中,形成类层次结构.因此,在领域模型中讨论继承没有意义,而当我们转向设计和实现视图时它才有重要意义.
association class
准则
在领域模型中增加关联类的可能线索有:
有某个属性与关联相关
关联类的实例具有依赖于关联的生命周期
两个概念之间有多对多关联,并且存在与自身相关的信息
aggregation & composite
准则
在下述情形下,可以考虑组合关系
- 部分的生命期在组成的生命期界限内,部分的创建和删除依赖于整体
- 在物理或者逻辑组装上,整体-部分关系很明确
- 组成的某些属性(例如位置)会传递给部分
- 对组成的操作(例如销毁,移动等)可能传递给部分
益处
有利于澄清部分对整体依赖的领域约束
有助于使用GRASP creator模式
对整体的复制,拷贝这些操作会传递给部分
时间间隔
文中举了一个价格变动的问题,提出了两种解决方案,一种是产品只记录当前价格,然后在销售时复制产品价格到订单,另一种方案是产品有多个价格.作者倾向于后者,因为这样有利于以后对价格变动进行分析.图形如下
作为概念的角色 & 关联中的角色
文中提到下面一种编码更清晰,但是不够灵活,无法处理一个人同时拥有多个角色的情况
导出元素
准则
要避免在图中显示导出元素,因为这些导出元素在没有增加新信息的情况下还会增加复杂性.然而,如果导出元素是重要的术语,而缺乏这一术语会削弱理解,这时就需要在图中增加导出元素.
对于上面的准则,书中给出的特例是Sale的total属性
受限关联
看上去让关联更清晰(也许能从Set转为Map),但是书中认为这个做法并不好,因为没有增加信息(我认为是增加了的),除非这种受限关联有价值,否则不用(在我看来,就是Map的key如果是自身的id的话就没啥用,如果是另一个东西的id也许就有用,特别的是指向current的指向)
类图
属性
三种方法
- 属性文本表示法
- 关联线表示法
- 两者皆有
属性文本格式
visibility name:type multiplicity=default(property-string)
准则:如果没有给出可见性,则通常假设属性是私有的
关联性
- 导航性箭头 由源对象指向目标对象
- 多重性放置在目标一端,而不是源一端
- 角色名只放置在目标一端,用以表示属性名称
集合
composition
组合关系有以下几层含义
- 在某一时刻,部分的实例只属于一个组成实例
- 部分必须总是属于组成(不存在游离的)
- 组成要负责创建和删除其部分,既可以自己来也可以与其他对象协作
个人观点,由于创建时总会有必填项与外键关联,所以上面要求组成要创建部分的限定不够厉害,而另一方面,几乎不存在删除操作,所以组成要删除部分的约束也没啥用
限定关联
当存在一对多,特别是一的一方的主键是多的一方的逻辑主键时,可以通过补充缺失的字段来锁定唯一
关联类
这个在DB中作为多对多的关系表,由于有了额外的属性,所以也就需要一个专门的类,为何不改成两个一对多的关系呢?我认为是改了之后就修改了原有的语义.(何况关联类可能是当初没有的,后来新增的,当然对设计不能大改)
方法
格式
visibility name(parameter-list):return-type(property-string)
准则:如果没有表示可见性,则通常假设操作是公共的
create
使用<<contructor>>来标识构造方法
getter
一般省略
关键字
关键字 | 含义 | 用法示例 |
---|---|---|
<<actor>> | 类元为参与者 | 置于类名称之上 |
<<interface>> | 类元为借口 | 置于类名称之上 |
{abstract} | 抽象元素,不能实例化 | 置于类元名称或操作名称之后 |
{ordered} | 具有强制顺序的一组对象 | 置于关联的端点 |
单实例类
作图上就是右上角标个1,我觉得还不如<<singleton>>来的明确,另外单实例类有点违背OO
主动类
active object运行于自己控制的执行线程之上.毫无疑问,主动对象的类即为主动类.在UML中,主动类使用左右两边为双竖线的类框来表示