JiveJdon的DDD聚合实现

上篇

聚合不变性

  通过仓储Repository 工厂来实现,我们在ForumMessage中设置一个embeded来表达该对象包括其内嵌的高聚合子对象是否被完整加载或操作。
在不变性设计中,我们还要考虑到缓存对象的一致性,因为我们所有的对象都被缓存,但是我们取出Message和Thread有先后,而Message和Thread之间互相引用,如何保证他们之间引用和缓存中的引用是同一个对象,这是必须构建不变性时考虑的。
在com.jdon.jivejdon.repository. ForumBuilder的getMessage方法,是这样:
ForumMessage getMessage(Long messageId, ForumThread forumThread)

这样,如果getMessage是被构建Thread是调用,那么调用者就把自己当前正在构建的Thread作为getMessage方法参数传入,保证构建Message中指引的Thread是自己。

可变性State

每次新增一个回帖ForumMessage,必然对其父贴的状态发生变化,也涉及到ForumThread中帖子前后状态的变化。

allowEdit则属于”特定的时刻通过事件处理“的属性,根据需求:只有帖子作者或超级管理员才可以修改,而只有等用户注册登录后这个事件发生,我们才可以判断,因此,allowEdit需要由外界触发判断,可以认为是每次客户端请求都要求进行判断的属性,可变频率更高,具体事件触发可通过服务形式被客户端请求出发。不过这种和具体客户端有关的属性不适合放入ForumMessageState这样全局性对象中,需要详细设计时更改。isEditing之类是否正在编辑等状态属性是需要的,这样如果当前帖子正在被编辑,那么其他用户就不能回复或修改。

其中isLeaf就是是否是叶子,也就是没有回帖等子贴,这是树形结构关系中一个重要的判断依据,根据业务需求,只有没有回帖才能修改,这个属性是判断依据,这个属性在每次回帖创建时,都要进行更新,属于CRUD中经常被更新项。
每次CRUD事件发生,特别是新帖增加和删除,还涉及到ForumThread状态的变化:

ThreadState中当前主题系列中帖子总数也是即时统计的,没有使用数据表一个字段来表达,好处是可以避免数据表频繁修改操作,减少一个方向的操作(读操作都必须)。
TreeModel中是通过一个Tree模型,来表达帖子回帖之间形成的树形结构关系,是保存在内存中,这样,有关树形特征都可以直接快速获取,不必频繁查询数据库。

设计细节约定

所有的时间串都是System.currentTimeMillis()获得,并以String类型持久保存到数据库中,然后在显示时转换为特定的格式,使用com.jdon.util.UtilDateTime.getDateTimeDisp转换成特定格式后给Model相应的时间赋值。这个工作在dao层实现,分别向两个方向(数据表和Model)赋值。
Property是所有Model的附加属性,比如帖子的IP地址等附件信息。Model和Property关系是1:N。
当然,以上建模只是粗放型,在以下具体设计中会对这些类进行细化。其实在以后的整个章节都是对业务建模不断修改的过程。

下篇