值对象如何共享

在看DDD时,说到 值对象不可以改变,于是就可以共享。
如果 值对象相同就都可以保持对它的引用,达到少创建值对象。
如下 假设,一个User 实体,Address是它的值对象


public class User
{
public int Id { get; set; }

public string Name { get; set; }

public Address Address { get; set; }
}

public class Address
{
public string CityName { get; set; }

public string AreaName { get; set; }
}

如果两个User实体的地址Address相同,怎么共享,代码编程怎么实现?
[该贴被linq于2012-12-18 17:01修改过]
[该贴被linq于2012-12-18 17:02修改过]

通过聚合根的getter方法共享外界。

最好方式是CQRS,值对象只能被外界读,那么走专门读取查询路线。

这样的话,为了共享 要去检索之前对象,如果没有相同的就创建新的,有相同的则把引用指向它,这个过程肯定要开销,为了共享有必要这样做吗?还不如直接创建新的??

时间与空间本来就是一对难兄难弟啊,呵呵~
具体情况具体分析么,采用不同策略’(甚至可以动态决策..用六、还是用九~)
[该贴被sinaID42847于2012-12-20 18:08修改过]

2012-12-19 09:04 "@linq"的内容
这样的话,为了共享 要去检索之前对象,如果没有相同的就创建新的,有相同的则把引用指向它,这个过程肯定要开销,为了共享有必要这样做吗?还不如直接创建新的?? ...

用值对象的目的是天生的共享性,他是无态的。注意,共享不是指两个User实体使用相同的Address,而是两条线程同时访问一个Address,即线程间的共享。

两个线程使用同一个值对象,就像你使用整形1一样,根本不会去考虑它会突然变成2。一个线程拿到值对象,不用顾虑其他线程突发地改变该值对象,锁、事务等为了解决共享问题的就无需考虑了。


2012-12-21 05:22 "@SpeedVan"的内容
用值对象的目的是天生的共享性,他是无态的。注意,共享不是指两个User实体使用相同的Address,而是两条线程同时访问一个Address,即线程间的共享。 ...

天生共享??
1。不同的线程, 都要去判断对象 是否已经创建,
那之前 创建的 都要保存到内存了? 只有保存了,后面的线程 在创建时,会去检索之前创建的,是不是这样理解?
如果保存了,是 怎么保存的?
2。检索的话,都是通过 聚合根 然后去找,是否是 有点麻烦?
大哥 再细细讲讲

2012-12-21 17:23 "@linq"的内容
天生共享??
1。不同的线程, 都要去判断对象 是否已经创建,
那之前 创建的 都要保存到内存了? 只有保存了,后面的线程 在创建时,会去检索之前创建的,是不是这样理解?
如果保存了,是 怎么保存的?
2。检索的话,都是通过 聚合根 然后去 ...

1、你这样考虑的是User,不是值对象Address本身了。若果你要User天生共享性而设计成值对象,那么User存在本身就要求Address而存在。

值对象的修改,可以无需考虑前面对象是什么,直接替换。当然也可以考虑,这就需要引入CAS了,或者原子化。

值对象天生共享性是,线程使用不需考虑其他线程的使用情况。例如Thread1使用Address1,无论你Thread2如何把Address1用Address2来替换,都对Thread1不会产生任何影响,推广到ThreadN和AddressN。

2、麻不麻烦因人而异,但有条理,怎么都比乱来的好。

2012-12-21 22:15 "@SpeedVan"的内容
值对象天生共享性是,线程使用不需考虑其他线程的使用情况。例如Thread1使用Address1,无论你Thread2如何把Address1用Address2来替换,都对Thread1不会产生任何影响,推广到ThreadN和AddressN。 ...

假设场景: Address 是值对象,现在要 创建 100个User,但是这100个User里头 Address有90个是相同的,这样的话,值对象如果共享的话,就可以 只声明 10+1=11 个 Address了,不用创建100个了。
是这种效果。
1.你说的 都不用管之前创建的,那怎么实现共享?
2.共享的话,我以为只是把 创建的引用地址指向之前创建的对象,不是直接替换原来的对象值,是不是这样理解?

2012-12-24 08:51 "@linq"的内容
假设场景: Address 是值对象,现在要 创建 100个User,但是这100个User里头 Address有90个是相同的,这样的话,值对象如果共享的话,就可以 只声明 10+1=11 个 Address了,不用创建100个了。
是这 ...

我不知道你到底哪里不解。建议你拿起JAVA线程共享的书,看着来对比我说的。

注:再重申一次,共享说的是线程间,不是对象间,因为只有线程间才会出现共享问题。

1、为什么共享要管之前的?你先搞清楚,何为共享。
2、我不太懂你到底想说明什么?

2012-12-24 14:52 "@SpeedVan"的内容
我不知道你到底哪里不解。建议你拿起JAVA线程共享的书,看着来对比我说的。 ...

你说的 线程之间 共享? 那是指不同的线程可以 调用的相同的方法。

我的 不是这个意思,我举的 例子 :
【Address 是值对象,现在要 创建 100个User,但是这100个User里头 Address有90个是相同的,这样的话,值对象如果共享的话,就可以 只声明 10+1=11 个 Address了,不用创建100个了。
是这种效果。】
是 DDD 著作中提到的值对象 共享,也不知道 我理解的对不对?
[该贴被linq于2012-12-24 17:46修改过]

2012-12-24 17:44 "@linq"的内容
【Address 是值对象,现在要 创建 100个User,但是这100个User里头 Address有90个是相同的,这样的话,值对象如果共享的话,就可以 只声明 10+1=11 个 Address了,不用创建100个了。
是这种效果。】 ...

对象间的共享,实际上是一种缓存技术,可参考JAVA的String实现,这只是优化手段,是一种模式——享元模式。值对象的确定本身就是其意义本身,并不是对象,值对象相等说的是值相等,跟是不是同一对象无任何关系,只要它们表达同一个意思就是相等。哪怕是100个Address,它在逻辑上跟11个的是一样的,也就是共不共享都可以。

从上可知这种对象间共享是可选的,是对值对象的一种使用方式,所以并不是值对象的天生共享性(对自身特性的描述),值对象的天生共享性来自值的不变性。其他就不多言了,多看看论坛过往的帖子。

string 驻留机制 是一个很好 建议,去研究研究,非常感谢!