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

08-05-19 freebox
         

模型:分类、书籍。

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

问题: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 下一页