请教关于DDD中,聚合根概念和相关实践的一些疑惑
第一次在解道发帖,如果有什么不当的地方还请大家多海涵。
楼主最近在做一个网页社交游戏的开发,探索性地开了个分支版本,准备实践DDD。
在游戏中,会有以下概念:
玩家:即用户,拥有一个唯一的标识符,还有姓名、年龄等属性。
道具:游戏中虚拟的物品,比如蘑菇、鲜花之类的,同名的道具标识符是相同的。
背包:每个玩家有且仅有一个背包,背包里边包含50个格子,但可以通过付费增加格子。
背包格子:用来存放道具,一个格子中只能存放一种道具,但数量不限。
数据库方面我们选用的是MongoDB,目前为上述概念建模如下:
{
"_id":4f7180ccfcac61af7106236b, //玩家唯一编号,类型为MongoDB的ObjectId;
"name":"Player", //玩家姓名
"age":20, //玩家年龄
"inventory":{ //玩家拥有的背包信息;
"slots":[ //背包内包含的所有格子信息;
{"_id":1,"item":1,"qty":3} //单个格子的编号、物品编号、数量
...中间省略49个格子信息...
]
}
}
由于MongoDB的松散结构,为每个玩家建模起来也相当方便。但问题也随之而来:
1、把user作为聚合根,那么是否每次存取user的时候都必须把inventory加载进来?
游戏设计师:“我们要有一个页面,让当前登录的玩家看到和TA年龄相差3岁以内的玩家名字!”
其实只需要获得age字段即可了,加载inventory似乎没有必要。
2、如果必须把inventory也一同加载,那么当为user增加其他的属性的时候,会不会造成更大的查询性能浪费?
游戏设计师:“我们还要为每个玩家增加私人的农场,每个农场有50块田!偷菜游戏什么的最好了。”
模型上没什么问题,可以像inventory一样为user增加farm和farmUnit即可。但随着类似需求的增多,恐怕噩梦不远。
3、当加载inventory的时候,是否有必要保留一个对user的引用?
前两个问题我个人感觉可以用内存缓存解决,但是同时又会引入一个新的问题。
比如我们需要每隔一段时间将所有的玩家年龄+1,不使用内存缓存的时候可以直接使用请求命令。(如:db.user.update({},{$inc:{"age":1},false,true});)
可当使用缓存之后,由于部分玩家数据在缓存中,不能直接使用update命令对数据库进行更新。而遍历时又会把所有用户都加载到内存里,那就真成噩梦了……
使用延迟加载似乎是个好主意,但是目前官方驱动中并没有实现这种功能,实在纠结。
希望各位达人慷慨相助,再次感谢。
[该贴被tecentIDD9EEA于2013-04-05 00:19修改过]