有个很有趣的问题,当实体中不是以聚合而是以查询的方式会出现什么让我们忽视的问题。

还是续上次与banq讨论的那个问题
ForumBoard与ForumSubject是一对多的关系如果设计成聚合便是
ForumBoard{
private List<ForumSubject> forumSubjects;
public List<ForumSubject> searchSubjectByTitle(String title)
//这个便是根据聚合内元素来找寻相应的ForumSubject对象
}
但如果遇到大数据量时与聚合的方式设计便是不太适合这时候我们便会想到以查询的方式不管事通过直接Repository还是
间接的DomainEvent模式还是什么的这个方法变成了查询来load这个对象
设计可能变成这样
ForumBoard{
private String title;
public List<ForumSubject> searchSubjectByTitle(String title){
//通过某种方式从数据库中load出对象
}
}
ok我通过我们设计做到了这点,但是有意思的问题总是藏得很深,深到让你不容易发现。我发现这个问题也是在同事的使用当中发现的。
先看主题对象的结构
ForumSubject{
private String title;
private ForumBoard forumBoard;//这是个与板块之间的关联
public getForumBoard(){...};
}
好有趣的代码来了
ForumBoard 板块 = loadForumBoard()从数据库中load出ForumBoard
ForumSubject 主题 = 板块.searchSubjectByTitle("某某主题");
ForumBoard forumBoard = 主题.getForumBoard();
forumBoard.title = "修改了板块名";
assertEquals(forumBoard.title,板块.title); //你猜会是什么事情发生。不相等。
//答案就是当searchSubjectByTitle是以查询的方式load对象时,我实际上是重现构建了个新的ForumSubject和ForumBoard之间的关系。他与原先的 板块 对象之间是脱钩的,这就使得 原先的 板块 对象 与 重新load出来的ForumSubject对象内的板块对象之间不存在任何关系。这就引申了个问题,当对象是聚合关系的时候我们ForumBoard对象内的引用关系是存在的,如果换成查询的话这种关系便打破了。
也许这时候会有朋友站出来说可以再把他补回去吗,如下:
ForumBoard{
private String title;
public List<ForumSubject> searchSubjectByTitle(String title){
//通过某种方式从数据库中load出对象
ForumSubject 重建出来的板块 = ForumSubject.getForumBoard();
Equals(重建出来的板块,this)//对比下两是否相等如果相等替换
ForumSubject.setForumBoard(this);
//这里替换,但是如果我们找出来的数据量大呢,那我们这样做所带来的时间上的耗费将有多大
}
}
有趣吧,希望大家一起来研究看看有啥好的主意没。


这就体现缓存的力量,通过缓存保证只要是一个实体类,就永远对应一个实体对象。 类与对象是一对一的。

那缓存当中的是引用,还是clone,如果是引用,那么当有一处是引用状态jvm可能就无法回收,缓存管理器也无法删除此对象的占用的空间,最多就只能删除对其引用的内存地址。如果是clone又变成新的对象,还是无法达到这个效果,如果换成hibernate去做,他的缓存是引用还是clone?我想大部分的缓存应该都会设置成clone。
[该贴被gamex于2009-10-19 13:53修改过]

缓存中的对象是不会出现回收问题的,因为多数缓存系统底层实现都是采用soft reference,当内存不够的时候,软引用对象会被清除。而弱引用对象是只要垃圾收集器启动就会收集的。

缓存当然是引用,依靠缓存器的算法LRU先进先出来维持不会变得无限大,当然,如果你使用分布式缓存或key-value,那么你的内存比关系数据库容量还大得多,是云存储了,就不存在内存限制,就没有垃圾回收等你考虑的这些底层问题。
[该贴被banq于2009-10-20 11:11修改过]

楼上,你的那位老师告诉你哈希表可以无限大??