领域建模的思想和方法(转)
2010-12-20 19:01 Dirichlet 阅读(6387) 评论(0) 编辑 收藏 举报转自:http://blog.csdn.net/zhaome/archive/2010/01/07/5154193.aspx
领域模型是作为设计软件对象的启发来源,也是后续工件的必须输入。
领域模型是说明问题域里(对建模者来说)有意义的领域类,它是面向对象分序的时候要创建的最重要的工作(必须说明,用例虽然也是一个重要的分析工作,但它并不是面向对象的,它是强调的概念的过程视图)。
一、领域建模的思想及其方法学问题
什么是“问题域”和“领域建模”?
问题域:
现实世界中系统所要解决问题的领域为“问题域”,如“银行业务”属于“银行的问题域”。
领域建模:
1.我们设计一个系统,总是希望它能解决一些问题,这些问题总是会映射到现实问题和概念。
2,对这些问题进行归纳、分析的过程就是领域建模(这个域,指的就是问题域)。
建立领域模型的好处:
1,通过建立领域模型能够从现实的问题域中找到最有代表性的概念对象
2,并发现出其中的类和类之间的关系,因为所捕捉出的类是反馈问题域本质内容的信息。
经典的面向对象的分析或调研的步骤,是把一个相关的领域,分解为单个领域类或者对象(是一个我们能够理解的概念)。
领域模型是领域类或者是我们感兴趣的现实对象的可视化表示。
它们也被称之为:概念模型、领域对象模型、分析对象模型等。
在UML中,领域模型是不定义操作(方法)的一组类图来说明,它主要表达:
1, 领域对象或者领域类
2, 领域类之间的关联
3, 领域类的属性
属性用以表达对象的状态。
(1)三种领域类
1,边界对象:参与者使用该对象与系统进行交流,也即边界对象代表系统的内部工作和它所处环境之间的交互。
边界对象将系统的其它部分和外部的相关事物隔离和保护起来。其主要的责任是:输入、输出和过滤。
2,实体对象:代表要保存到持续存储体中的信息。实体类通常用业务域中的术语命名。
通过它可以表达和管理系统中的信息。在模型中,系统中的关键概念以实体对象来表现。其主要的责任是:业务行为的主要承载体
3,控制对象:它协调其他类的工作,每个用例通常有一个控制类,控制用例中的时间顺序。
它可能是与其它对象协作以实现用例的行为,控制类也称管理类。其主要的责任:控制事件流,负责为实体类分配责任
有四个规则对应上面的三种分析类对象间的交互
1,用例的参与者只能与边界对象交互(这相当于结构化分析里面的自动化边界)
2,边界对象只能与控制对象和动作者交互(即不能直接访问实体对象)
3,实体对象只能与控制对象交互
4,控制对象可以和边界对象交互,也可以和实体交互,但是不能和动作者交互
三种领域类的UML的图示如下:
(2)领域建模的简单例子
下面举个简单的例子,说明领域建模的基本概念。
1)问题的描述
例如:两个领域类Payment(支付)Sale(售出)在领域模型中以一种有意义的方式关联。
2)关键概念
仔细考察上面的图,可以看出,领域模型实际上是可视化了领域中的单词或领域类,并且为这些单词建立了领域类。
也就是说,领域模型是抽象了一个可视化字典。
模型展现了部分视图或抽象,而忽略了建模者不感兴趣的细节。
它充分利用了人类的特点—大脑善于可视化思维。
3)领域模型不是软件组件的模型
领域模型视相关现实世界领域中事务的可视化表示,不是Java或者C#类这样的软件组件。
下面这些元素不适合在领域模型中表述:
1,软件工件(窗口或数据库)
2,职责或者方法:方法是个纯粹的软件概念,在设计工作期间考虑对象职责是非常重要的,但领域模型不考虑这些问题,在这里考虑职责的正确方法是,给对象分配角色(比如收银员)。
4)领域类
领域模型表示领域中的领域类或词汇,一个不是太准确的描述:一个领域类就是一个观点、事务或者对象。
比较准确的表达:
领域类可以按照它的符号、内涵和外延来考虑。
l 符号:代表一个领域类的单词或者图片。
l 内涵:领域类的定义。
l 外延:领域类定义的一组实例。
二、领域类的识别
我们的目标是在相关领域中创建有意义的领域类。
比如说创建“处理销售”用例中的相关领域类。
一般来说,用大量细粒度的领域类来充分描述领域模型,比粗略描述要好。
下面是识别领域类的一些指导原则:
l 不要认为领域模型中领域类越少越好,情况往往恰恰相反。
l 在初始识别阶段往往会漏掉一些领域类,在后面考虑属性和关联的时候才会发现它,这是应该把它加上。
l 不要仅仅因为需求中没有要求保留一些领域类的信息,或者因为领域类没有属性,就排除掉这个领域类。
l 无属性的领域类,或者在问题域里面仅仅担当行为的角色,而非信息的角色的领域类,都可以是有效的领域类。
1)识别领域类的策略
下面提供了两种识别领域类的技巧。
1. 使用领域类分类列表。
2. 识别名词短语。
2)使用领域类分类列表
通过建立一个候选的领域类的列表,来开始建立模型。下面是一个从商店和航空订票领域中抽取出来的概念列表(注意,排列不考虑重要性)。
领域类分类
示例
物理或具体对象
(略)
事物的设计、描述、或规范
位置
交易
交易项目
人的角色
其它事物的容器
容器包含的元素
在该计算机之外的其它计算机或电子机械系统
抽象名词的概念
组织
过程(通常不表示一个概念,但可以被表示成一个概念)
规则和政策
分类
有关工作、契约和法律事务的记录
财务设施及服务
手册、文档、引用论文、书籍
3)根据名词短语识别找出领域类
曾经有人提出了用名词短语分析找出领域类的方法,然后把它们作为候选的领域类或者属性。使用这种方法必须十分小心,从名词机械的映射肯定是不行的,而且自然语言中的单词本来就是模棱两可的。
不过,这仍然是灵感的另一种来源,比如,我们来看一看原来写出来的“处理销售”的用例:
基本流程:
1.顾客携带购买的商品到达POS机收费口
2.收银员开始一次新的销售
3.收银员输入商品标识
4.…..
重复 3 – 4 步,直到结束。
5.………
…….
10.顾客携带商品和收据离开
仔细研究其中的名词,可以看到很多有用的领域类(“记账”、“提成”),也可能有些是属性,请研究我们后面要讨论的关于区分属性的和类的讨论。
这种方法的缺点就是不精确,但对我们研究问题会非常有用。
推荐:
把领域类分类,和词语分析一起使用。
三、领域建模的指导原则
1)事物的命名和建模
领域模型是问题域中的概念或这是事物的地图,所以地图绘制员的策略,也适用于领域模型的建模。
l 使用地域中已有的地名(和城市名相同)
l 排除不相关的特性(比如居民人数)
l 不添加不属于某个地方的事物(比如虚构的山川)
以此,我们建议使用如下的原则:
l 给领域模型建模,要使用问题域中的词汇。
l 把和当前不相关的领域类排除在问题域之外。
l 领域模型应该排除不在当前考虑下的问题域中的事物。
2)在识别领域类的时候一个常犯的错误
在建立领域模型的时候,最常犯的一个错误就是把原本是类的事物当作属性来处理。
Store(商店)是Sale(出售)的一个属性呢?还是单独的领域类Store?
大部分的属性有一个特征,就是它的性质是数字或者文本。
而商店不是数字和文本,所以Store应该是个类。
另一个例子:
考虑一下飞机订票的问题,Destination(目的地)应该是Flight(航班)的属性呢还是一个单独的类Airport(包括属性name)。
在现实世界中,目的地机场并不是数字和文本,它是一个占地面积很大的事物,所以应该是个领域类。
建议:
如果我们举棋不定,最好把这样的事物当做一个单独的领域类,因为领域模型中,属性非常少见。
四、分析相似的领域类
有一些情况是比较不太容易处理的。
举个例子,我们来分析一下“Register(记录)”和“POST(终端)”这两个概念。
POST作为一个销售终端,可以是客户端任何终点的设备(用户PC,无线PDA),但早期商店是需要一个设备来记录(Register)销售。
而POST实际上也需要这个能力。
可见,Register是一个更具抽象性的概念,在领域模型中,是不是应该用Register而不是POST吗?
我们应该知道,领域模型其实没有绝对正确和错误之分,只有可用性大小的区分。
根据绘图员原则,POST是一个领域中常见的术语,从熟悉和传递信息的角度,POST是一个有用的符号。
但是,从模型的抽象和软件实现相互独立的目标来看,Register是一个更具吸引力和可用性的表达,它可以方便的表达记录销售位置的概念,也可以表达不同的终端设备(如POST)。
两种方式各具优点,关键是看你的领域类重点是表达什么信息。
这也是一个架构师必备的能力—抓住重点。
五、为非现实世界建模
一些业务领域有自己独特的概念,只要这些概念是在业内被认可的,同样可以创建领域类,比如在电信业可以建立这样的领域类:
消息(Message)、连接(Connection)、端口(Port)、对话(Dialog)、路由(Route)、协议(Protocol)等。
六、规格说明或者描述领域类
在领域模型中,对领域类作规格说明的需求是相当普遍的,因此它值得我们来强调。
假定有下面的情形:
l 一个Item实例代表商店中一个实际存在的商品
l 一个Item表达一个实际存在的商品,它有价格,ID两个描述信息
l 每次卖掉一个商品,就从软件中删掉一个实例。
如果我们是这样来表达:
那很可能会认为随着商品的卖出,它的价格也删掉了,显然这是不对的。
比较好的表达方式是这样的:
1)何时需要规格说明类
在下面的情况下,需要添加领域类的说明类:
l 商品或服务的信息描述,独立于商品或者服务当前已经存在的任何实例。
l 删除所描述的事物,会导致维护信息的丢失。
l 希望减少冗余或者重复的信息。
2)服务的描述
作为领域类的实例可以是一次服务而不是一件商品,比如航空公司的航班服务。
假定航空公司由于事故取消了6个月的航班,这时它对应的Flight(航班)软件对象也在计算机中删除了,那么,航空公司就不再有航班记录了。
所以比较好的办法是添加一个FlightDestination(航班目的)的规格描述类,请看下面的例子。
七、统一过程中的领域模型
根据“统一过程的时间及其时间安排”的那张表,在UP中,通常在细化阶段开始并完成领域模型的建模。事实上,对于一个有经验的系统构架师,在每次迭代里开发领域模型,只需要几个小时就够了。
在UP中,有一个业务对象模型(BOM),但实际上并不通用,而领域模型实际上是BOM的一个正是的变体。在RUP中,BOM是这样来定义的:它是业务员和业务实体如何相关联,以及为了完成业务如何写作的抽象。
BOM可以用多种不同的图(类图、活动图、顺序图)来表示,这些图说明整个企业应该如何运行。
不过对于单个软件的应用,这似乎是个不太通用的活动。尽管它还有一些变通,但是在系统架构设计中,领域模型仍然是最为广泛的被采用的。
第二节 领域模型的关联
一、找出关联
关联,是类(事实上是实例)指示有意义或相关连接的一种关系。
关联事实上表示是一种“知道”。
如果不写箭头,关联的方向一般是“从上到下,从左到右”。
我们可以使用下面的表来找出关联
分类
示例
A在物理上是B的一部分
(略)
A在逻辑上是B的一部分
A在物理上包含在B中/依赖于B
A在逻辑上包含在B中
A是对B的描述
A是交易或者报表B中的一项
A为B所知道/为B所记录/为B所扑获
A是B的一个成员
A是B的一个组织子单元
A使用或者管理B
A与B通信
A与一个交易B有关
A是一个与另一个B有关的事物
A与B相邻
A为B所拥有
A是一个与B有关的事件
二、关联的指导原则
l 把注意力集中在那些需要把概念之间的关系信息保持一段时间的关联(“需要知道”型关联)。
l 太多的关联不但不能有效的表示领域模型,分而会使领域模型变的混乱,有的时候发现某些关联很费时间,但带来的好处并不大。
l 避免显示冗余或者导出的关联。
三、角色和多重性
关联的每一端称之为“角色”。
角色可选的具有:
名称;
多重性表达式;
导航性。
多重性
多重性表示一个实例,在一个特定的时刻,而不是一段时间内,可以和多个实例发生关联。
“*”表示多个。
“1”表示一个。
“0..1”表示1或者没有,比如一个商品在货架上,可能售出,也可能被丢掉了,这种情况,用“0..1”是合理的。问题是我们需要关心这样的观点吗?如果是数据库,可能表达这个数据存在,或者损坏。但在领域模型并不表示软件对象,通常我们只对我们有兴趣的内容建模,从这个观点出发,也可能只有“1”或者“*”是合理的。
再一次提醒,发现领域类比发现关联更重要,花费在领域模型创建的大部分时间,应该被用于发现领域类,而不是关联。
四、两种类型之间的多重关联
两种类型之间的多重关联是可能存在的。
比如航空公司的例子,Flight-to和Flight-from可能会同时存在,应该把它们都标出来。
第三节 领域模型的属性
发现和识别领域类的属性,是很有意义的。
属性是个逻辑对象的值。
属性主要用于保留对象的状态。
一、有效的属性类型
大部分属性应该是简单数据类型。
当然也可以使其它的一些必要的类型,比如:Color(颜色)、Address(地址)、PhoneNumber(电话号码)等。
二、非原始的数据类型类
在领域类中,可以把原始数据类型改成非原始数据类型,请应用下面的指导原则:
l 由分开的段组成数据(电话号码,人名)
l 有些操作和它的数据有关,如分析和验证等(社会安全号码)
l 包含其它属性的数据(促销价格的开始和结束时间)
l 带有单位的数据值(支付金额有一个货币单位)
l 对带有上述性质的一个或多个抽象(商品条目标识符)
如果属性是一个数据类型,应该显示在属性框里面。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaome/archive/2010/01/07/5154193.aspx