请教这个应该当成值对象属性吗?

freebox 08-05-19
         

模型:分类、书籍。

class Category{
Category parent;
List<Category> children;
CategoryState state;
}
class Book{
Category category;
}
class CategoryState{
int bookCount=0;
}

问题:bookCount应该如何设计。
说明:
现在有需求查询各级分类中书籍的数量bookCount。
由于分类下不断增加子分类,现在想查询最顶层的分类中的书籍数量,需要遍历顶级分类的所有子分类并递归,最后求和,效率比较低下。
查询和增加Book都比较频繁。
请教这种情况应该如何设计,是否应该把bookCount设计在Category中并在增加Book时更新分类及所有父级分类?或有更好的方法查询这种分类树。

         

killer
2008-05-22 19:17

>>>是否应该把bookCount设计在Category中并在增加Book时更新分类及所有父级分类?

个人感觉在新增和查询比较频繁的情况下可以这么做,对于增加Book时更新分类及所有父级分类,可以放在事件里面在,让它自动触发执行

freebox
2008-05-22 22:28

你的意思是建触发器在DB级别处理?或是由对象关联不断检索它的直接、间接根对象一层层更新?
这两种效率都不太高。
目前采取为Category建立间接子结点树和间接父结点树的方式处理,需要维护一个ManyToMany关系,查询用了in查询,暂时先看看,因为对Category的更新并不多,建立Category之后就基本稳定了。

banq
2008-05-26 11:08

>查询最顶层的分类中的书籍数量,需要遍历顶级分类的所有子分类并递归,最后求和
这是典型的composite模式使用场景,建议使用composite模式进行求和,将分类树形的遍历封装起来。

至于是否当成值对象,我觉得没有必要这样教条,只要使用模式来参与实现,具有一定解耦性就是适当设计了,DDD也说没有设计准则和定理,所以,你也不能拿DDD本身概念往上靠。这些都是范了形式主义倾向。

freebox
2008-05-26 12:27

非常感谢banq先生对我的问题的关注。
最初的设计就是这么做的,因为Category本身持有的父子都是它自己或自己的集合,实现也容易。给了一个专用的查询树和其子树的Book数量的查询器,但是他们说查询一层中的一个父结点就需要发出10多条SQL,认为不合理,树太高,而Book随时增加,缓存似乎用处也不大。
目前试验使用间接子树结点统计,每个父结点都拥有它的所有子结点的标识集合,统计一层的一个父结点的bookCount只需要一个in查询。

2Go 1 2 下一页