有个很有趣的问题,当实体中不是以聚合而是以查询的方式会出现什么让我们忽视的问题。
还是续上次与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);
//这里替换,但是如果我们找出来的数据量大呢,那我们这样做所带来的时间上的耗费将有多大
}
}
有趣吧,希望大家一起来研究看看有啥好的主意没。