一个对象多处引用的维护问题

我想大家在应用开发的时候都有过这种经历 。

一个对象在a处创建了,但b处又需要引用它。这样就有了两个引用
当在a处删除的时候 ,希望在b处也删除它;如果系统稍大的时候,可能多次引用的次数会更加多,一一删除很繁琐。 有没有办法一处删除 ,别处也同时删除,至少把引用置为null,下次能识别出来。

一般情况下,可以用工厂方式,不在多地保持该对象的应用. 只保留一处, 其它地方都从该地获得.
但我们这个系统前期是一家高校的老师开发的,id号是id1、id2...这样连续的,id2删除,id3补到id2。对象连个唯一的标识都没有。

用工厂模式也不知道怎么定位对象?


其实这个问题的本质就是Evans DDD中的领域对象生命周期问题,通过工厂和Rep保证领域对象和其内嵌聚合子对象的一致性,或者称不变性。

这种删除等操作级联方式,象Hibernate等ORM框架都提供了这样的功能,所以,这也是使用这些框架的一个大优点。

如果自己使用JDBC实现,就比较麻烦,而且还要注意扩展性,以后再多一个子对象,还要改动一次,不象hibernate等配置或注解一下就可以。

至于象你这个系统,可以直白说:没有办法了,因为开始设计时就不对,这也是软件设计要讲科学的原因。

如果不是领域对象,而是一些功能类,那么可以考虑IOC/DI这样自动autowiring方式来实现。

这两天仔细修改了,给每个对象添加了唯一不变的globalId。取得对象引用的时候都用get(String globalId),只在一个地方保留引用,别的地方只记录globalId。当get(globalId)返回为空就清除之。

有些人的习惯是一个对象保持多处引用,这种方式虽然运行效率高些,但维护会很麻烦。

如果只在一处保留引用,别处只保留globalId,用get方法或者工厂返回引用,返回后的引用不保留,用完就扔。 这种方式扩展性较好

在多线程那本书里介绍了一种安全拷贝的方法,每次传递引用的时候将上一个引用删除掉,这样保证对象象接力棒一样同时只能有一个引用,一般情况下没问题,除非多线程并发访问,只有在多线程的环境里才允许有多个引用

楼上其实是说明了一个原理,就是尽量不要多处引用(80%的情况下是不需要的),如果必须需要,应当遵循谁产生谁管理的原则。

这两天仔细修改了,给每个对象添加了唯一不变的globalId。取得对象引用的时候都用get(String globalId),只在一个地方保留引用,别的地方只记录globalId。当get(globalId)返回为空就清除之。

有些人的习惯是一个对象保持多处引用,这种方式虽然运行效率高些,但维护会很麻烦。

如果只在一处保留引用,别处只保留globalId,用get方法或者工厂返回引用,返回后的引用不保留,用完就扔。 这种方式扩展性较好
---------------------------
但这种办法的效率有点问题,原来多出保留引用可以直接用,现在每次都要从list或者hash表中查找,效率低。如果是一般业务软件无所谓,碰上图形软件就麻烦了。

可以考虑使用智能指针类似的实现方式。内部维护一个计数器,每次引用计数器自动加一,每次删除计数器自动减一,当计数器为0的时候,自己删除自己。每处的引用必须要负责释放,程序看起来也会清晰很多。而且不会因为一个地方删除而导致其他地方出现错误的问题。

可以考虑使用智能指针类似的实现方式。内部维护一个计数器,每次引用计数器自动加一,每次删除计数器自动减一,当计数器为0的时候,自己删除自己。每处的引用必须要负责释放,程序看起来也会清晰很多。而且不会因为一个地方删除而导致其他地方出现错误的问题。
------------------------------
这倒是一个办法。

在对象里添加一个方法setNull(),在=null之前先执行

可以考虑使用 代理模式。

所有的对象都通过代理来解决。


代理1控制引用生效周期
Object Ref 1 --------| ---- Real Protected Object
Object2 Ref 2--------|


[该贴被abayi于2009-01-09 20:39修改过]

十分希望java api(System类)里能提供返回所有系统内对象(数组)的方法,也能查看每个对象都在那个方法里引用的路径..

try catch 呵呵 :)

楼主的问题java里是有解决办法的,弱引用WeakReference就是你的要求吧?