pub兄粗心啦
Leg() {
// Needed by Hibernate
}

// Auto-generated surrogate key
private Long id;
这几行代码难道您没看到?即使没看到您也应该看看hibernate的配置文件嘛。

>,对同一领域,一拨采用OO进行建模,一拨采用数据建模,我相信最终的结果会相差不大

这个观点应用在软件分析上很危险,建议有这个想法的人读读Martin Fowler的 分析模式 这部经典巨著。

这本书,在他的前言中他就说了:通过本书的模型同David Hay的模型进行比较,会很强烈地感受到软件技术如何影响概念建模(banq:软件技术不应该影响业务概念建模,这是常识),我们都尽力想建造概念模型,然而我们的结果却有很大的不同,因为他使用的是关系技术,而我使用面向对象技术。

这几天重读DDD,对值对象又有深入理解,学而时习之,不也乐乎,我的理解是:学了再去用它,然后再回来复习,又获得新认识。

回到正题:从ForumMessage角度来看,ForumThread是一个值对象,这点比较肯定,因为它记录整个帖子的一些共同特性;目前,ForumThread中一些属性不全是值对象特征,特别是ForumThread中状态子对象,用来表示当前帖子最新更新时间等状态,这个状态更新时,我们必须具体更新缓存中某个特定的状态对象,否则更新错了,用户主题列表查询时,没有看到这个帖子发生最新更新,所以,由此断定,ForumThread中状态子对象不属于值对象部分,应该从ForumThread剥离出来。

当初我将ForumThread作为实体,也是主要考虑了状态子对象这个特点,现在看来将状态子对象放到ForumRootMessage这个实体中去比较合适。

我发现在这里ForumThread应该是一个实体,理由如下:

Evans DDD中谈到地址是否是值对象,在不同领域范围里,它有时是有时不是,邮购软件中的地址是值对象:用地址作为发货目的地。如果住在一起多个室友邮购,不影响邮递,有名字作为标识。电力运营软件中地址是实体:如果住在一起多个室友申请电力服务,电力公司必须区分。

邮政软件中的地址是实体:将地区分层次结构,区 城市 街道 邮编 个人地址。

ForumThread由来主要是一个集合类,是代指一系列围绕一个根贴讨论的很多帖子集合,从这个概念初步看,好像应该是值对象,如果它仅仅附属在根贴后面,用户不需要根据标识来直接寻找ForumThread。

但是,主题列表偏偏是罗列所有的ForumThread,那么用户需要根据标识来定位某个具体ForumThread。

值对象只关心what,不关心which或who,由于用户首先从Forum找到ForumThread,才能找到ForumRootMessage,还有一个重要原因,ForumThread在实现时是保存在缓存中,一般保存在缓存中对象基本都是实体。

值对象是无需缓存的,它可以复制,通过自我复制克隆,也可以大家共享唯一一个值对象,从这两点来看,ForumThread不具备。

当然,你可以说,一个ForumThread中所有帖子不是共享一个ForumThread吗?注意,前提必须是这个ForumThread下,值对象应该是论坛所有帖子都共享一个,这才只是关注what,而不关心who or which,实际所有帖子共享的ForumThread不是全局唯一,而是有分别的。

所以,ForumThread最终落实为实体,以上是我思考过程,欢迎讨论。
[该贴被banq于2009-04-08 09:09修改过]

banq 终于回到正题上了。

“是不是值对象”这个问题,需要具体业务具体分析。就好像之前有个人,非要弄个值对象也要存储。你说都存储了(有唯一标示),还能说它是值对象吗?

>>>是不是值对象”这个问题,需要具体业务具体分析。就好像之前有个人,非要弄个值对象也要存储。你说都存储了(有唯一标示),还能说它是值对象吗?

从这句话中导出:您认为值对象不需要储存。您认为储存了的对象就称之为实体.
我感觉您过早下结论。

一个应用中需要从数据库中加载地址的信息供用户选择,应用只关系地址的值,而不区分这个地址跟那个地址的区别。这明显是一个值对象。但他需要从数据库中加载同时列表出来,如果没ID(数据库主键),那如何加载出来(使用ORM)?

我认为ForumThread为值对象明确一点的原因是:forumthread没有DDD Identity(但有数据库 ID),forumthread借用了ROOTMessage的Identity.虽然我们需要将ForumThread列表出来,但我们只是进行展示,而不进行修改,要修改得找到聚合跟,也就是RootMessage,当修改的时候我们重新创建出一个ForumThread就可以。

总结:ValueObject与DDD Entity最根本区别就在于是否具有Identity和是否需要修改。

>是不是值对象”这个问题,需要具体业务具体分析。就好像之前有个人,非要弄个值对象也要存储。你说都存储了(有唯一标示),还能说它是值对象吗?

这句话应该不是我说的,至少现在我没有这个意思,不会以存储来判断是否值对象的,见这个帖子:
http://www.jdon.com/jivejdon/thread/35836.html

同意"ValueObject与DDD Entity最根本区别就在于是否具有Identity"

但是您加了“是否需要修改”这个定语,我觉得需要好好理解一下,是否你从值对象的不变性得出的,但可能这两者不是同一个意思。

我们可能对“是否具有Identity”的理解有些分歧:
1.目前我认为找出ForumThread实际就是分辨,这个找不是随便找,而是定位某个ForumThread。
2.我同意RootMessage是一个聚合的根,那么是不是除此以外得就是它的叶或枝呢?未必,ForumThread应该包容RootMessage聚合根和它的枝叶的容器,类似小组实际是人员的容器一样。

这有点类似于Order和Product之间我们引入OrderLine,按MF的说法,OrderLine是一个关联类,但是我觉得可以在实际订单上找到订单行,它是一个包容Product和数量QTY的容器实体。

刚看了一篇老外的"Your Entity Object Is My Value Object"
你的实体是我的值对象,文中以牛奶盒为例,对于消费者,牛奶盒都一样,随便拿一个出来喝就可以,所以对于消费者是值对象,但是对于生产厂,每个牛奶盒上有生产日期批次,就是实体了。

http://jonathan-oliver.blogspot.com/2009/01/ddd-your-entity-object-is-my-value.html
[该贴被banq于2009-04-09 09:51修改过]



yinyousong :
一个应用中需要从数据库中加载地址的信息供用户选择,应用只关系地址的值,而不区分这个地址跟那个地址的区别。这明显是一个值对象。但他需要从数据库中加载同时列表出来,如果没ID(数据库主键),那如何加载出来(使用ORM)?

我想讨论的是:当我们讨论领域模型的时候,不要扯上数据库。你管我领域模型怎么存储呢?是不是?
你和之前那个同志一样,把 数据库主键 和 唯一标示 搞混了。
例如对于 用户 这个模型,我可以认为 userId 是唯一标示,但是在数据库中,我可以使用一个自动增加的字段 id 作为主键。

ok,回到你那个问题上。 “地址信息”这个东西,如果像你那么应用,确实它是值对象。
但是,换个场合,例如管理员需要一个后台维护“地址信息”这个功能,这个时候你还能说它是值对象?很明显,每个地址都是实体!

所以我说,实体和值对象没什么区别,都是领域模型,非要说区别,也得在具体的业务环境下讲。所以所以,回到 ddd 的源头:为啥我们要区分出实体和值对象?那还不是为了让我们清晰的掌握业务逻辑吗?难道 evans 是为了“大师”这个头衔而创造这个词汇?

所以,我觉得有些人,整天讨论 “实体和值对象区别”,“值对象是否需要存储”等等话题很没意思。

>值对象是否需要存储
这个问题不应该在建模分析设计时考虑,而是实现时考虑,这是大家统一的。

>实体和值对象区别
这个需要讨论,因为都是实体一种模型的话,那么当模型一多的时候,就会看到密密麻麻蜘蛛网一大堆,没有主次,这个分类类似于四色建模中四种颜色,彩色UML颜色,也是为加强直观认识,这些我归结为“象”。对象是否存储属于数范围,是具体执行操作层面。

“>实体和值对象区别
这个需要讨论,”

是应该在“特定的业务范围”内讨论。脱离的业务范围去讨论就没有意义了。


“那么当模型一多的时候,就会看到密密麻麻蜘蛛网一大堆”

这个问题不应该怪罪于“实体对象多”。解决的方法应该是:为什么实体对象多?如果实体对象真的就那么多,那么这个应用程序是不是应该分解成多个独立的部分?

所以,出现蜘蛛网的时候,要么是分析错了,要么是整体的设计需要改变了。而不能因为出现了蜘蛛网,就潜意识的去主动寻找值对象。

我觉得ForumThread符合DDD里值对象叙述中的特殊情况那一段。

可能是我对jivejdon的需求没彻底的弄懂吧,其实我一直觉得有些对象是不是值对象很难分辨,要看具体的需求。项目前期某个对象可能属于值对象,而随着需求的明确,它又可能成为实体。


to:yananay
我还以为是你没有弄懂DB identity与DDD identity呢。
看来我们讨论错了。
讨论值对象与实体有助于找到模型的切入点,有助于分析领域.

大家都是在讨论时间渐进过程中对需求迭代深入理解,角度不一样,没有对错,只有合适与否。

实体和值对象搞清楚,实际就是搞清楚主次之分,值对象应该附属于实体,是实体的补充说明描述,因此本身就不需要独立出来,这里面有相当的主观成分,这也是面向对象的一个特点。

以老外牛奶为例,消费者为什么认为牛奶盒是值对象,因为他重点是喝牛奶;就象画画,主要是同种颜色 笔尖一样,拿哪个都一样,因为我们主要重点是画画,不是削笔尖。

所以,实体和值对象区分可以帮助我们搞清楚Domain范围的重点,这有非常重要的意义。

值对象包含一个List集合的情况呢?大家讨论下