领域模型
目标:
- 确定与当前迭代相关的概念类
- 创建初始的领域模型
- 为模型建立适当的属性和关联
领域模型是OO分析中最重要的和经典的模型。它阐述了领域中的重要概念。领域模型可以作为设计某些软件对象的灵感来源,也将作为在案例研究中所探讨的几个制品的输入。本章将介绍创建领域模型的基本技术。
领域模型的范围限定于当前地带所开发的用例场景,领域模型能够被不断地演进用以展示相关的重要概念。相关的用例概念和专家的观点作为创建领域模型的输入。反过来,该模型又会影响操作契约、词汇表和设计模型,尤其是设计模型中的领域层的软件对象。

示例
对领域模型应用UML类图表示法会产生概念透视图模型。
确定一组概念类是OO分析的核心。如果能通过熟练和快速的调查来完成这项工作,那么通常会在设计过程中得到回报,因为领域模型能够支持更好的理解和沟通。
什么是领域模型
这一精髓的面向对象分析步骤是从领域到重要概念或对象的分解。
领域模型是对领域内的概念类或现实世界中对象的可视化表示。领域模型也成为概念模型、领域对象模型和分析对象模型。
在UP中,术语”领域模型“指的是对现实世界概念类的表示,而非软件对象的表示。该术语并不是指用来描述软件类、软件架构领域层或有职责软件对象的一组图。
UP对领域模型的定义是,可以在业务建模科目中创建的制品之一。更准确地将,UP领域模型是UP业务对象模型的特化, ”专用于揭示业务领域中重要的‘事物’或产品“。也就是说,领域模型专注于特定领域。更为广泛的BOM是扩展的,通常十分庞大和难以创建的多领域模型,BOM覆盖整个业务及其所有子域。
应用UML表示法,领域模型被描述为一组没有定义操作的类图。它提供了概念透视图。它可以展示:
- 领域对象或概念类。
- 概念类之间的关联。
- 概念类的属性。
定义:为什么把领域模型称为”可视化字典“
领域模型描述的信息也可以采用纯文本(UP词汇表)表示。但是可视化语言中更容易理解这些术语,特别是它们之间的关系,因为我们的思维更擅长理解形象额元素和线条链接。因此领域模型是可视化字典,表示领域的重要抽象、领域词汇和领域的内容信息。
定义:领域模型是软件业务对象图吗
UP领域模型是对所关注的现实世界领域中事物的可视化,而不是注入Java或C#的软件对象,或有职责软件对象。因此以下元素不适用于领域模型:
- 软件制品
- 职责或方法。
定义:”领域模型“的两个传统含义
UP中,”领域模型“是现实世界中对象的概念透视图,而非软件透视图。但这一术语是多义的,也用来表示”软件对象的领域层“也就是说,在表示层或UI层之下的软件对象曾是由领域对象组成的--领域对象是表示问题领域空间事物的软件对象,并且与”业务逻辑“或”领域逻辑“方法相关。
在本书中,通常会使用领域层来表示领域模型针对软件的第二个含义。
定义:什么是概念类
领域模型阐述领域中的概念类或词汇。通俗的说,概念类是思想、事物或对象。更正式地将,概念类可以从其符号、内涵和外延来考虑:
- 符号:表示概念类的词语或图形。
- 内涵:概念类的定义。
- 外延:概念类所适用的一组示例。
定义:领域模型和数据模型是一回事吗
领域模型不是数据模型,所以在领域模型里,并不会排除需求中没有明确要求记录其相关信息的类,也不会排除没有属性的概念类。
动机:为什么要创建领域模型
动机:降低与OO建模之间的表示差异
这是OO的关键思想:领域层软件类的名称要源于领域模型中的名称,以使对象具有源于领域的信息和职责。这样就可以减小我们的思维与软件模型之间的表示差异。
准则:如何创建领域模型
以当前迭代中所要设计的需求为界:
- 寻找概念类。
- 将其绘制为UML类图中的类。
- 添加关联和属性。
示例:寻找和描绘概念类
找到概念类的三条策略
- 重用和修改现有的模型。这是首要、最佳且最简单的方法,如果条件许可,通常从这一步开始。在许多常见领域中都存在已发布的、绘制精细的领域模型和数据模型。
- 使用分类列表。
- 确定名词短语。
方法2:使用分类列表
我们可以通过制作概念类获选列表来开始创建领域模型。
| 概念类的类别 | 示例 |
|---|---|
| 业务交易 | Sale、Payment、Reservation |
| 交易项目 | SalesLineItem |
| 与交易或交易项目相关的产品或服务 | Item、Flight、Seat、Meal |
| 交易记录于何处 | Register、Ledger、FlightManifest |
| 与交易相关的人或组织的角色:用例的参与者 | Cashier, Customer, Store, MonopolyPlayer, Passenger, Airline |
| 交易的地点:服务的地点 | Airport, Plane, Seat, Sale, Payment, MonopolyGame, Flight |
| 管理对象 | Item, Register, Board, Piece, Die, Airplance |
| 事物的描述 | ProductDescription,FlightDescription, ProductCatalog, FlightCatalog |
| 事物(物理或信息)的容器 | Store,Bin, Board, Airplane |
| 容器中的事物 | Item, Square(在棋盘上),Passenger |
| 其他协作的系统 | CreditAuthorizationSystem, AirTraffficControl |
| 金融、工作、合约、法律材料的记录 | Receipt,Ledger, MaintenanceLog |
| 金融手段 | , Cash, Check,LineOfCredit,TicketCredit |
| 执行工作所需的进度表、收测、文档等 | DailyPriceChangeList, RepairSchedule |
方法3:通过识别名词短语寻找概念类
语言分析,即在对领域的文本型描述中识别名词和名词短语,将其作为获选的概念类或属性。
使用这种方法是必须消息。不可能存在名词到类的映射机制,并且自然语言中的词语具有二义性。
详述形式用例中的描述对这种分析极为适合。
领域模型是重要领域概念和词汇的可视化。那么从哪里找到这些术语?其中某些术语来源于用例。另外一些术语则源于其他文档,或是专家的相反。
其中一些名词短语是候选的概念类,有些名词所指的该你了可能会在本次迭代中忽略,还有一些可能只是概念类的属性。
示例:寻找和描绘概念类
案例研究:POS领域
根据分类列表和名词短语分析,可以得到该领域候选概念类的列表。因为这是业务信息系统,所以首先要关注分类列表中强调业务交易及其与其他事物关系的哪些项目。该列表仅限于当前为迭代1所考虑的需求和简化的处理销售用例,即基本的现金交易场景。
没有什么所谓”正确“的列表。上述列表中的抽象事物和领域词汇在一定程度上是随意手机的,但都是建模者认为重要的。尽管如此,基于下面的识别策略,不同建模者还是会得到类似的列表。
准则:敏捷建模--绘制类图的草图
准则:敏捷建模--是否要使用工具维护模型
在早期的领域建模过程中,通常会遗漏一些重要的概念类,而在后来进行草图设计或编程时,会发现这些类。如果采用敏捷建模方法,创建领域模型的目的时为了快速理解和沟通大致的关键概念。完美不是戳,面积模型在创建后通常很快就被抛弃了。基于这种观点,则没有理由去维护或更新这些模型。
如果有人在由新发现时想要维护和更新模型,那么这是使用UML CASE工具重新绘制白板操作的很好理由,或者从最开始使用工具来绘制并且使用计算机投影仪。但是要问问自己:谁要使用这些更新的模型?为什么?如果不存在实际的理由,则无需多此一举。通常,进化的软件领域层对大部分重要术语会给与提示,而且长生闷气的OO分析领域模型不会增加价值。
准则:报表对象--模型中是否要包括”票据“
票据时POS领域的重要术语。但也许它只是销售和支付数据的报表,因此,时一种信息的重复。那么是否应该将票据包含在领域模型中呢?
以下时一些需要考虑的因素:
- 一般来说,在领域模型中显示其他信息的报表并没有意义,因为其所有信息都是源于或复制与其他信息源的。这是排除它的理由。
- 另一方面,就业务规则而言,它有特殊的作用:通常持有票据的人有退货的权力。这是在模型中要表示它的源于。
业务在本次迭代中没有考虑退货,所以不应该包括票据。在解决处理退货用例的迭代中,我们会考虑将其包含在内。
准则:像地图绘制这一样思考:使用领域术语
地图绘制者的策略既可以用于地图,也可以用于领域模型。
已地图绘制者的工作思维创建领域模型:
- 使用地域中现有的名称。
- 排除无关或超出范围的特性。
- 不要凭空增加事物。
准则:如何对非现实世界建模
有些软件系统的领域与自然领域或业务领域几乎没有乐死指出,然而还是有可能为这些领域创建领域模型。此时需要高度的抽象,对常见的非OO设计进行回顾,并且认真汲取领域专家所使用的核心词汇和概念。
准则:属性与类的常见错误
在创建领域模型是最常见的错误是,把应该是概念类的事物标识为属性
如果我们认为某概念类X不是先死世界中的数字或文本,那么X可能是概念类而不是属性。
准则:何时使用”描述“类建模
描述类包含描述其他事物的信息。这种类被明明为项目-描述复模式。
动机:为什么使用描述类
以下讨论初看起来似乎是和汉奸、非常特殊的问题有关的。然而,这表明在许多领域模型中,描述类是常见的。
假设如下:
- Item实例表示商店里实际的商品;统一,它也可以拥有一个序列号。
- Item具有描述、架构和ID,这些内容不会在任何其他地方记录。
- 商店的每个工作人员都有健忘症。
- 没售出一些实际的商品,相应的Item软件实例就会从”软件领域“中删除。
基于这些假设,在以下场景中会发生什么状况?
收欢迎的心事汉堡ObjectBurger,在市场上有巨大的需求。商店销售一空,也意味着ObjectBurger的所有Item实例都从计算机存储器中被删除。
现在,存在一个问题,即如果有人询问, ”ObjectBurger多少钱“,没人能够回答。因为架构是记录在存货实例上的,当这种汉堡买完以后就没有记录了。
还有一些相关的问题。如果软件实现模型类似于领域模型,则其中含有重复数据,这回降低空间利用效率并可能产生错误,因为描述、价格和ID对于同一产品的每个Item实例来说都是重复的。
上述问题表明,对象需要其他事物来记录其描述。为解决Item问题,需要ProductDescription类来记录商品的信息,ProductDescription并不代表Item,而是表示哟管商品的描述信息。
准则:何时需要描述类
以下i情况需要增加描述类:
- 需要有关商品或服务的描述,独立于任何商品或服务的现有实例。
- 删除其所描述事物的实例后,导致信息丢失,而这些信息是需要维护的,但是被错误写与所删除的事物关联起来。
- 减少冗余或重复信息。
实例:航空领域中的描述
关联
找到并表示出关联是有助的,这些关联能够满足当前所开发场景的信息需求,并且由于住理解领域。
关联是类(更精确地说,是这些类的实例)之间的关系,表示有意义和值得关注的连接。
在UML中,关联被定义为”两个或多个雷元之间的语义联系,涉及这些类元实例之间的连接“。
准则:何时表示关联
关联表示了需要持续一段时间的关系,根据语境可能是几毫秒或数年。换言之,我们需要记录哪些对象之间的关系?
由于领域模型是从概念的角度出发的,所以是否需要记录关联,要基于现实世界的需要,而不是基于软件的需要,尽管在实现过程,会有出现大量对关联的需要。
在领域模型中要考虑如下关联:
- 如果存在需要保持一段世界的关系,将这种语义表示为关联。
- 从场景管理列表中派生出的关联
准则:为什么应该避免加入大量的关联
连线太多会产生”视觉干扰“,使图变得混乱。所以要谨慎地增加关联线。
观点:关联是否会在软件中实现
在领域建模过程中,关联生命的使针对现实领域从纯概念角度看有意义的关系。
也就是说,这些关系的大部分将作为导航和可见性路径在软件中加以实现。但是,领域模型不是呼叫模型;添加关联使为了突出哦我们对重要管理的大致理解,而非记录对象或数据的结构。
应用UML:管理表示法
关联被表示为类之间的连线。关联的末端可以包含多重性表达式,用于指明类的实例之间的数量关系。关联本质上使双向的。可选的”阅读导向箭头“只是阅读关联名称的方向:但它并不表示可见性或导航的方向。
以”类名-动词短语-类名“的格式为关联明明,其中的动词短语构成了刻度的和有意义的顺序。

应用UML:角色
关联的每一端称为角色。角色具有如下可选项:
- 多重性表达式。
- 名称
- 导航
应用UML:多重性
多重性定义了类A有多少个实例可以和类B的一个实例关联。
多重性的值表示在特定时刻(而不是在某个时间跨度内)有效关联的实例数量。
多重性的值和建模者和软件开发者的关注角度有关,因为它表达了将要在软件中反映的领域约束。
应用UML:两个类之间的多重关联
在UML类图中,两个类之间可能会有多重关联。
准则:如何在常见关联列表中找到关联
| 类别 | 示例 |
|---|---|
| A是与交易B相关的交易 | CashPayment-Sale Cancellation-Reservation |
| A是交易B中的一个项目 | SalesLineItem-Sale |
| A是交易(或项目)B的产品或服务 | Item-SalesLineLine(或Sale) Flight-Reservation |
| A是交易B相关的角色 | Customer-Payment Passenger-Ticket |
| A 是B的物理或漏极部分 | Drawer-Register Square-Board Seat-Airplane |
| A被逻辑地或物理地包含在B中 | Registe-Stroe,Item-Shelf Square-Board Passenger-Airplane |
| A是B的描述 | ProductDescriptin-Item FlightDescription-Flight |
| A在B中被感知/即日至/记录/生成报表/捕获 | Sale-Register Piece-Square Reservation-FlightManifest |
| A是B的成员 | Cashier-Store Player-MonopolyGame Pilot-Airline |
| A是B的组织和子单元 | Department-Stor Manitenance-Airline |
| A使用/管理/拥有B | Cashier-Register Player-Piece Pilot-Airplane |
| A与B相邻 | SalesLineItem-SalesLineItem Square-Square City-City |
示例:领域模型红的关联
案例研究:NextGenPOS

案例研究:Monopoly游戏

属性
确定概念类的属性是有助的,能够满足当前所开发常见的信息需求。属性是对象的逻辑数据值。
准则:何时展示属性
当需求建议或暗示需要记住信息时。
应用UML:属性表示法
更多表示法
准则:在哪里记录属性需求
建议把所有这种属性需求置于UP词汇表中。
导出属性
当我们需要表达:这是重要贤惠能干,但是导出的,那么可以使用UML的约定:在属性名称前加以”/“符号。
准则:什么样的属性类型时适当的
关注领域模型中的数据类型属性
通俗的说,大部分属性类型应该时”简单“数据类型。通常,属性的类型不应该时复杂的领域概念。
通过关联而不是属性来表示概念类之间的关系。
数据类型
领域模型中的属性通常应该时数据类型。一般来说,数据类型是“基本”类型。更准确地讲,UML术语中的数据类型指的是一组值,而这组值的表示本身不具有任何含义。
观点:代码中的属性
在领域模型中建议属性主要为数据类型,并不意味着C#或Java的属性只能是简单的基本数据类型。
准则:何时定义新的数据类型类
下述情况,在领域模型里,把最初被认为是数字或字符串的数据类型表示为新的数据类型类:
- 由不同的小节组成
- 具有与之相关的操作
- 具有其他属性
- 单位的数量
- 具有以上性质的一个或多个类型的抽象。
应用UML:在何处描述这些数据类型类
准则:任何属性都不表示外键
应使用关联而不是属性来将类型关联起来。
对数量和单位建模
大部分用数字表示的数量不应该表示为纯数字。应该给这些数量加上单位,并且通常还需要指导单位之间的转换关系。一般情况下,可以把数量表示为单独的Quantity类,并且关联到Unit类。
示例:领域模型中的属性
案例研究:NextGen POS

案例研究:Monopoly

结论:领域模型是否正确
没有所谓唯一正确的领域模型。所有模型都是对我们试图要理解的领域的近似。领域模型主要是在特定群体中用于理解和沟通的工具。有效的领域模型捕获了当前需求语境下的本质抽象和理解领域所需要的信息,并且可以帮助人们理解领域的概念、术语和关系。
过程:迭代和进化式领域建模
尽管以及用例很大篇幅对领域建模进行揭示,但实际在每次迭代中对该模型进行开发只需30分钟而已。
在迭代开发中,我们会通过若干迭代对领域模型进行增量地研究。在每个迭代中,领域模型都会限定于之前和档期啊要考虑的常见,而不是膨胀为瀑布风格的“大爆炸”模型,以过早试图捕获所有可能的概念类和联系。
UP中的领域模型
UP中的领域模型通常开始和完成于细化阶段。
初始
初始阶段绝不会发起领域模型,因为初始阶段的目标不是继续宁严格的调查,二十决定项目是否值得在细化阶段进行深入调查。
细化
领域模型主要是在细化阶段的低矮中创建的,这是最需要理解哪些重要概念,并且会通过设计工作将其映射为软件类。
UP 业务对象模型与领域模型
UP领域模型是较少见的UP业务对象模型的正式变体。UPBOM是一种描述整个业务的企业模型。BOM可以用来进行业务过程工程或再工程,而不依赖于任何软件应用。
UP BOM 作为抽象,描述的是业务人员和业务实体应该怎样关联,以及它们如何协作以完成业务。
BOM 使用不同的图来阐述整个企业是如何运转的。BOM通常有助于进行企业范围的业务过程工程,而在创建单个软件应用时并不常见。
因此,UP定义了领域模型,作为BOM的常用制品子集或特化。引证如下
你可以选择开发“非完整的”业务对象模型,重点解释领域中的重要“事物”和产品。[...]这些都称为领域模型。