表示模型的3种模型元素模式:ENTITY、VALUE OBJECT和SERVICE。从表面上看,定义那些用来捕获领域概念的对象很容易,但要想反映其含义却很困难。这要求咱们明确区分各类模型元素的含义,并与一系列设计实践结合起来,从而开发出特定类型的对象。数据库
我的理解:就是实体类(entity),VALUE OBJECT(值对象,我没懂)和服务(service),开发人员一看就懂了。性能优化
对象之间的关联使得建模与实现之间的交互更为复杂。模型中每一个可遍历的关联,软件中都要有一样属性的机制。架构
一个显示了顾客与销售表明之间关联的模型有两个含义。一方面,它把开发人员所认为的两个真实的人之间的关系抽象出来。另外一方面,它至关于两个Java对象之间的对象指针,或者至关于数据库查询(或相似实现)的一种封装。框架
例如,一对多关联能够用一个集合类型的实例变量来实现。但设计无需如此直接。可能没有集合,这时可使用一个访问方法(accessor method)来查询数据库,找到相应的记录,并用这些记录来实例化对象。这两种设计方法反映了同一个模型。设计必须指定一种具体的遍历机制,这种遍历的行为应该与模型中的关联一致。数据库设计
现实生活中有大量‚多对多‛关联,其中有不少关联天生就是双向的。咱们在模型开发的早期进行头脑风暴活动并探索领域时,也会获得不少这样的关联。但这些广泛的关联会使实现和维护变得很复杂。此外,它们也不多能表示出关系的本质。分布式
至少有3种方法可使得关联更易于控制。性能
(1) 规定一个遍历方向。优化
(2) 添加一个限定符,以便有效地减小多重关联。设计
(3) 消除没必要要的关联。指针
尽量地对关系进行约束是很是重要的。双向关联意味着只有将这两个对象放在一块儿考虑才能理解它们。当应用程序不要求双向遍历时,能够指定一个遍历方向,以便减小相互依赖,并简化设计。理解了领域以后就能够天然地肯定一个方向。
我的理解:上面的内容技术人员不要看啦,很难理解,我告诉你是怎么一回事。技术角度就是两个对象的关联关系以下:一对一(一我的一个鼻子),一对多(一我的两个手臂),多对多(一我的报名多个课程,一个课程有多我的报名)。是否是很像数据库设计模型?
开始讲故事:能够不听,由于我会用一句话总结,很是简单。
软件系统中的大多数‚ENTITY‛并非人,也不是其一般意义上所指的‚实体‛或‚存在‛。ENTITY能够是任何事物,只要知足两个条件便可,一是它在整个生命周期中具备连续性,二是它的区别并非由那些对用户很是重要的属性决定的。ENTITY能够是一我的、一座城市、一辆汽车、一张彩票或一次银行交易。
一位女房东起诉了我,要求我赔偿她房屋的大部分损失。诉状上是这样写的:房间的墙上有不少小洞,地毯上尽是污渍,水池里的脏物散发出的腐蚀性气体致使厨房墙皮脱落。法庭文件认定我做为承租人应该为这些损失负责,依据就是个人名字和我当时的地址。这把我彻底搞糊涂了,由于我从未去过那个被损坏的房子。
过了一下子,我意识到这必定是认错人了。我给原告打电话,告诉她这一点,但她并不相信我。几个月以来,上一位租客一直在躲避她。如何才能证实我不是那个破坏她房屋的人呢?如今电话簿里只有一个Eric Evans名字,那就是我。仍是电话簿成了个人救星。因为我在这所公寓里已经住了两年,因而我问她是否还有去年的电话簿。她找到了电话簿,发现有与我同名的人(我就在那我的下面),她意识到我不是她要起诉的那我的,因而向我道歉,并答应撤销起诉。
计算机可不会这么‚神机妙算‛。软件系统中的错误标识将致使数据破坏和程序错误。
主要由标识定义的对象被称做ENTITY[。ENTITY(实体)有特殊的建模和设计思路。它们具备生命周期,这期间它们的形式和内容可能发生根本改变,但必须保持一种内在的连续性。为了有效地跟踪这些对象,必须定义它们的标识。它们的类定义、职责、属性和关联必须由其标识来决定,而不依赖于其所具备的属性。即便对于那些不发生根本变化或者生命周期不太复杂的ENTITY,也应该在语义上把它们做为ENTITY来对待,这样能够获得更清晰的模型和更健壮的实现。
固然,软件系统中的大多数‚ENTITY‛并非人,也不是其一般意义上所指的‚实体‛或‚存在‛。ENTITY能够是任何事物,只要知足两个条件便可,一是它在整个生命周期中具备连续性,二是它的区别并非由那些对用户很是重要的属性决定的。ENTITY能够是一我的、一座城市、一辆汽车、一张彩票或一次银行交易。
当一个对象由其标识(而不是属性)区分时,那么在模型中应该主要经过标识来肯定该对象的定义。使类定义变得简单,并集中关注生命周期的连续性和标识。定义一种区分每一个对象的方式,这种方式应该与其形式和历史无关。要格外注意那些须要经过属性来匹配对象的需求。在定义标识操做时,要确保这种操做为每一个对象生成惟一的结果,这能够经过附加一个保证惟一性的符号来实现。这种定义标识的方法可能来自外部,也多是由系统建立的任意标识符,但它在模型中必须是惟一的标识。模型必须定义出“符合什么条件才算是相同的事物”。
在现实世界中,并非每个事物都必须有一个标识,标识重不重要,彻底取决于它是否有用。实际上,现实世界中的同一个事物在领域模型中可能须要表示为ENTITY,也可能不须要表示为ENTITY。
我的理解:一句话,设计实体的时候最好有一个全局惟一id的属性。相信作技术的会以为,上面说了这么多就是这个意思,太简单了,没错,就是这么简单,关键是,咱们有本事写那么多的字来表述(瞎扯)吗?
不少对象没有概念上的标识,它们描述了一个事务的某种特征。当一个小孩画画的时候,他注意的是画笔的颜色和笔尖的粗细。但若是有两只颜色和粗细相同的画笔,他可能不会在乎使用哪一支。若是有一支笔弄丢了,他能够从一套新笔中拿出一支一样颜色的笔来继续画,根本不会在乎已经换了一支笔。
问问孩子冰箱上的画都是谁画的,他会很快辨认出哪些是他画的,哪些是他姐姐画的。姐弟俩有一些实用的标识来区分本身,与此相似,他们完成的做品也有。但设想一下,若是孩子必须记住哪些线条是用哪支笔画的,状况该有多么复杂?若是这样的话,画画将再也不是小孩子的游戏了。
因为模型中最引人注意的对象每每是ENTITY,并且跟踪每一个ENTITY的标识是极为重要的,所以咱们很天然地会想到为每一个领域对象都分配一个标识。实际上,一些框架确实为每一个对象分配了一个惟一的ID。
这样一来,系统就必须处理全部这些ID的跟踪问题,从而致使许多原本可能的性能优化不得不被放弃。此外,人们还须要付出大量的分析工做来定义有意义的标识,还须要开发出一些可靠的跟踪方式,以便在分布式系统或在数据库存储中跟踪对象。一样重要的是,盲目添加无实际意义的标识可能会产生误导。它会使模型变得混乱,并使全部对象看起来千篇一概。
我的理解:VALUE OBJECT 能够理解entity去掉惟一性的id,变成了无状态的一个对象。
VALUE OBJECT能够是其余对象的集合。在房屋设计软件中,能够为每种窗户样式建立一个对象。咱们能够将‚窗户样式‛连同它的高度、宽度以及修改和组合这些属性的规则一块儿放到‚窗户‛对象中。这些窗户就是由其余VALUE OBJECT组成的复杂VALUE OBJECT。它们进而又被合并到更大的设计元素中,如‚墙对象。
VALUE OBJECT常常做为参数在对象之间传递消息。它们经常是临时对象,在一次操做中被建立,而后丢弃。VALUE OBJECT能够用做ENTITY(以及其余VALUE)的属性。咱们能够把一我的建模为一个具备标识的ENTITY,但这我的的名字是一个VALUE。
当咱们只关心一个模型元素的属性时,应把它归类为VALUE OBJECT。咱们应该使这个模型元素可以表示出其属性的意义,并为它提供相关功能。VALUE OBJECT应该是不可变的。不要为它分配任何标识,并且不要把它设计成像ENTITY那么复杂。
有时,对象不是一个事物。在某些状况下,最清楚、最实用的设计会包含一些特殊的操做,这些操做从概念上讲不属于任何对象。SERVICE是做为接口提供的一种操做,它在模型中是独立的,它不像ENTITY和VALUE OBJECT那样具备封装的状态。SERVICE是技术框架中的一种常见模式,但它们也能够在领域层中使用。所谓SERVICE,它强调的是与其余对象的关系。与ENTITY和VALUE OBJECT不一样,它只是定义了可以为客户作什么。SERVICE每每是以一个活动来命名,而不是以一个ENTITY来命名,也就是说,它是动词而不是名词。SERVICE也能够有抽象而有意义的定义,只是它使用了一种与对象不一样的定义风格。SERVICE也应该有定义的职责,并且这种职责以及履行它的接口也应该做为领域模型的一部分来加以定义。操做名称应来自于UBIQUITOUS LANGUAGE,若是UBIQUITOUS LANGUAGE中没有这个名称,则应该将其引入到UBIQUITOUS LANGUAGE中。参数和结果应该是领域对象。
好的SERVICE有如下3个特征。
(1) 与领域概念相关的操做不是ENTITY或VALUE OBJECT的一个天然组成部分。
(2) 接口是根据领域模型的其余元素定义的。
(3) 操做是无状态的。
我的理解:就是面向接口的设计,提供的就是服务。
MODULE是一个传统的、较成熟的设计元素。每一个人都会使用MODULE,但却不多有人把它们当作模型中的一个成熟的组成部分。代码按照各类各样的类别进行分解,有时是按照技术架构来分割的,有时是按照开发人员的任务分工来分割的。甚至那些从事大量重构工做的开发人员也倾向于使用项目早期造成的一些MODULE。MODULE之间应该是低耦合的,而在MODULE的内部则是高内聚的。耦合和内聚的解释使得MODULE听上去像是一种技术指标,仿佛是根据关联和交互的分布状况来机械地判断它们。然而,MODULE并不只仅是代码的划分,并且也是概念的划分。一我的一次考虑的事情是有限的(所以才要低耦合)。不连贯的思想和“一锅粥”似的思想一样难于理解(所以才要高内聚)。
低耦合高内聚做为通用的设计原则既适用于各类对象,也适用于MODULE,但MODULE做为一种更粗粒度的建模和设计元素,采用低耦合高内聚原则显得更为重要。这些术语由来已久,早在[Larman 1998]中就从模式角度对其进行了解释。
我的理解:包,关注高内聚低耦合就对了。