领域模型设计
企业应用软件很简单。它主要包括三个部分:一个领域模型,一组基于领域模型的计算,以及用来和用户交互的界面。这是一个基本的思路。
领域模型在工作时会涉及信息的使用和存储。因为存储的需要,所以要了解数据库(现在的ORMapping工具使你不用更多地了解它)。
我们知道,企业级信息系统需要解决的是领域问题,而不单单是数学运算问题。
领域问题最终会转化为一个个数学运算,但是在求解领域问题的过程中,仅仅依靠数学知识是远远不够的。 例如,保险公司的承保业务,不仅需要大量的信息数据,还需要复杂的业务逻辑。要描述这些业务逻辑,必须站在领域的高度上进行。
Java语言对于数据结构中的数据类型进行了新的抽象,引入了类和对象的概念。因为这个概念的引入,一次新的面向对象的革命产生了。
Java语言恰好是进行面形思维的一个好工具。 为什么这么说呢?因为Java语言引入了类和对象的概念。这使得这种语言的使用者从单纯的逻辑思维中跳了出来。人们开始发现,编程语言与领域世界是如此贴近,以至于人类的想象几乎可以完整地从软件系统中再现出来
分清问题域和问题解决域
一 领域与领域模型
俗话说,人人心中有一个Hamlet,人人心中也都有一个领域模型的定义。
常见的有:
说法1
领域是对业务工作进行归类划分,归类的方式是业务工作具有相关的知识,这些所需要的知识构成一个领域,这些知识是业务工作的背景,通过对领域的分析,可以帮助我们挖掘、分析、理解业务工作的本质。 也就是说,领域是为需求分析工作服务的,它的目的是挖掘、分析、理解业务工作的本质。
说法2
领域模型就是对领域内的概念类和现实世界中对象的可视化表示。
说法3
企业应用架构模式中明确提出了三种领域逻辑组织模式:事务脚本、领域模型和表模块。领域模型同时将行为和数据作为领域逻辑的核心。
从上面可以3种说法,可以看到不同上下文不同的观点,甚至未必是同一个表达对象。企业应用架构模式中的领域模型是设计到实现层的一个概念,而说法1,说法2种的领域是业务层面及分析阶段的一个概念。因此,本文特指[领域模式]为业务视角的模型,引用定义如下:
领域: 是相对于系统而言的,是系统要解决的现实问题。 领域模型: 是对领域内的概念类或现实世界中对象的可视化表示(百度) 领域模型是针对某个特定问题的所有相关方面的抽象模型(Wikipedia)
二 领域模型=ER?
领域模型是否就是ER模型呢?答案是否定的,领域模型是特定业务域业务实体关系的自然浮现,而ER是设计阶段数据库实现关系的产物。
三 领域建模=DDD?
一说领域建模就提及DDD, 是大家的自然反应。因为DDD(2004年著名建模专家Eric Evans发表了他最具影响力的著名书籍:
Domain-Driven Design –Tackling Complexity in the Heart of Software)
的知名度颇高。DDD顾名思义是模型驱动设计,是从需求打通到设计阶段的方法。
域模型的几个概念:
域(domain)
子域(subdomain):
语境(context):
是一个特定人群在讨论的问题域是所形成的上下文。 这里要强调一个概念, 特定人群不是以团队或者是项目为边界划分的人群, 而是以知识为边界来划分的人群。 也就是说上下文不是普遍存在的, 而是存在于一个人群内部的,并且这些上下文大多是以隐形知识(Tacit Knowledge)的方式而存在的。 什么是隐形知识呢, 就是还没有被总结整理归纳沉淀的知识。 举例来说说商品会有一个独立详情页和商铺详情页的概念, 这两个概念的准确定义和他们的商业目标的定义目前还没有显现化。 但是几乎团队内的每个人都能分别出这两个概念和他们所关联的问题。 这就是一个语境(Context)。
特定语境(Bounded context):
是把上下文限定到某个特定的边界之内。 这个边界是由某个特定人群和他们所讨论的问题子域来决定的。 举例来从电子商务,到商品, 到商品发布, 到规则,到商品审核规则是从大到小的问题域,他们对应的特定语境就是越来越细分并且越来越准确的上下文, 而对应的人群也是越来越小并且越来越专业。 最常见的bounded Context就是某个国际标准组织, 他们会为自己的标准定义专业的名词, 语法, 和表达方式。 而一个大的标准,比如说Health Level 7 (HL7), 总共有数千的会员。 这些人又组成了更小的标准委员会。标准委员会内又有更小的讨论组。 这就形成的从大到小的分级。而另外一个医疗标准, DICOM,又形成了另外一个bounded context。
语境映射(Context Mapping):
不同的语境之间会有交互, 那么从一个语境到另一个语境的翻译过程就是语境映射。 比如说刚才提到的HL7是一个医疗标准。 而DICOM是一个医疗图像标准。 每个语境有一套完整准确的定义。 那么当某个场景需要我们在两个语境之间做交互的时候, 我们就需要Context Mapping 了。 举个例子来说,一个普通咳嗽的病人可能会被医生推荐去做胸透, 那么信息就需要从一个只能理解HL7(医疗语境)的系统交换到DICOM(医疗图像语境)的系统。 那么在HL7系统中的模型就需要无损的映射到DICOM系统中去。 这就是个映射的例子。
域语言(Ubiquitous Language):
实体(Entity):
触发事件(Domain Event):
数值对象(Value Object):
实体类型(Entity Type):
关系(Relationship):
场景(Scenario):
核心场景(Core Scenario):