JiveJdon分析设计
导航: 上一页
角色设计:Anonymous普通用户;注册用户User;管理者Admin;
普通用户用例功能:
浏览所有论坛;
浏览所有帖子;
浏览其他用户信息;
本系统总体设计实现思路是:首先使用基于Model使用Jdon框架将整体结构搭建出来,实现基本功能,然后在这个基础结构上进行细化,就如同绘画,首先打出轮廓,这样把握整体结构,然后再进入详细表达。
建模
根据用例图,找出原始模型,复杂的用例,我们可以借助四色图帮助我们分类,本案例用例由于我们都比较熟悉,能够从用例中找出一些被操作对象,这些被操作对象大概有几个:Account用户 Forum论坛 ForumMessage帖子。
这里注意一个特殊情况,论坛不是直接并行的多个帖子组成,这些帖子之间也有回复关系,也就是说,回复帖子肯定不是论坛的直接组成成分,这里非常类似订单案例:订单中有多个商品,但是商品不是订单的直接组成部分,有可能有两个相同商品,每个商品还对应一个新属性数量,商品和数量联合起来才可能是订单的组成部分,这个联合起来的对象是订单条目,订单条目才是订单的直接组成部分。
在当前案例,论坛和帖子之间也需要一个类似订单条目的概念,订单条目可能看不见摸不着,它的组成部分就是商品和数量,订单条目其实是一个集合概念,那么在论坛和帖子之间其实也存在这样一个集合概念:FourmThread,如下:
ForumThread相当于主题Topic; 但Topic主要内容放入rootMessage中,可以说相当于所有rootMessage的主题提要,包括回复rootMessage的最后的一个回帖,包括rootMessage在内的所有帖子数等,主要服务于显示一个论坛中所有rootMessage集合。
ForumThread和Forum之间是N:1关系ForumMessage相当于帖子;ForumMessage之间有一个父子关系,表示帖子之间回帖关系;ForumMessage和ForumThread之间是N:1关系,和Forum之间也是N:1关系。
领域模型图如下:
Evans DDD在领域对象的生命周期中对不变性(invariant)进行了定义,指无论何时数据发生变化,都必须满足所有对象一致变化的规则。
围绕ForumMessage,其组成部分Fourm ForumThread Account都是其核心部分,就像汽车由发动机 车身 轮胎组成一样,缺一不可。特别是ForumThread和ForumMessage,更是这种不变性的高度统一,ForumThread实则是虚的,它里面实体就是ForumMessage,两者是高度一致的。
DDD指出;聚合内部的不变量必须在每次事务完成时满足。这可有仓储来实现。
当然,还有一些依赖关系只能在某些特定的时刻,通过事件处理、批处理和其他更新机制来实现,比如上图中state和tag 以及property。
不变性实现
通过仓储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。
当然,以上建模只是粗放型,在以下具体设计中会对这些类进行细化。其实在以后的整个章节都是对业务建模不断修改的过程。