DDD的一次小实践,在线学习。

13-08-09 showerxp
用户学习用例场景

1、系统显示课程列表。

2、用户选择其中一个课程查看内容。

3、用户决定学习该课程。

4、系统根据用户之前的学习该课程记录,决定用户学习哪一个章节,并显示给用户看。

5、用户学完该章节之后,系统列出对应的测试题。

6、用户回答测试题,系统判断是否正确。

7、系统根据课程设置的规则,判断是否有效学习,如果有效则记录用户学习时间和章节,如果不是有效学习则提醒用户如何有效学习。

8、用例结束。

局部图1

局部图1


局部图2

说明:软件模型关注重点是用户学习交互过程,没有包括课程、章节、测试等对象的创建,修改,删除等内容,因为这部分就目前业务需求来说,除了CURD,没有涉及的领域知识。

聚合根:课程、节点、学习记录。

困惑点:课程是否该包涵节点Id。思前想后,我这里包涵了节点Id,虽然课程和节点都是聚合根,这样一个聚合根对象拥有一群另外一聚合根对象Id似乎很别扭。我这么做可以找到领域内的解释,就像学生之于班级,班级名册只要记录学生名称,而不要学生本人。

难点:聚合根对应的仓库如何优雅的处理聚合的实体和值对象状态的改变,直白的说就是如何处理聚合实体和值对象的CRUD,特别是有些值对象的删除和修改。比如章节的仓库如何处理小测试实体的新增和修改等操作。似乎除了引入事件,还真没有其他优雅的方法。当然,我用php的魔法方法实现AOP,也可以比较好的处理这类通用的垂直操作。

[该贴被showerxp于2013-08-09 17:46修改过]

[该贴被showerxp于2013-08-09 17:47修改过]

[该贴被showerxp于2013-08-09 17:49修改过]

[该贴被showerxp于2013-08-09 17:49修改过]

    

3
xianghx
2013-08-12 21:51
章节包含课程,要不课程里要有数组,如果业务允许,单向关联的好处理些。

章节需要课程,但课程可以跳过某个章节的。

聚合根被引用没问题,只要不是内部的就行。最好就引用一个标识就可以了。

还有上面的图里的学习,不是个实体,好像只起到关联的作用,不应存在。

不知道这个应用的关注点是什么,具体的业务核心是什么。先找出核心的业务,其他的可以先放一放。

showerxp
2013-08-12 22:30
章节也就是图中的节点,包涵的是课程“Id”。同样课程包涵一连串的章节“Id”。

我认为,一个聚合根绝对不能引用另一个聚合根(包括任何形式的依赖关系)。但是可以引用或者持有另一个聚合根的Id。我上面就业务前面已经解释了:一个班级可以有学生的花名册(学生Id),一个学生清楚的知道自己在哪个班级(班级Id)。如果一个聚合根被另一个聚合根引用——也就是持有,那会出现什么问题呢?比如这么个业务:学校开运动会,小明代表他所在班级(班级Id)参加100米跑。如果班级持有小明,会出现班级站在跑道上参加比赛的情况。这是荒谬的!因为小明作为一个“人”有跑的行为,小明的班级是没有跑的行为,如果班级引用的小明,那么班级也间接的有“跑”的行为,从而可以参加跑步比赛了。

因此,我把学习当做一个service,大家在“学习”这个舞台实现章节和课程的交互。就好像“比赛”也是一个舞台一样,各个班级的代表选手在这个舞台实现他们之间的交互。

具体的业务流程已经在用例场景中写明白了,这些就是核心业务。现在用我设计的这些类实现了。

[该贴被showerxp于2013-08-12 22:31修改过]

xianghx
2013-08-13 13:27
班级==》学生==》 课程==》章节==》测试==》学习记录(结果)

public class Class{

id,name

method()

}

public class ClassId{

id,name

}

public class Student{

id,name,classId

method()

}

班级不一定要包含学生。

如果需要,再加就可以了。

一个聚合根绝对不能引用另一个聚合根(包括任何形式的依赖关系)??

这谁说的,没听说过。也不能够呀。只听说除了聚合根,其他的不可直接引用呀。

班级有小明的行为,好奇怪的说法。不知道你怎么写的,代码帖出来看看。

showerxp
2013-08-13 17:55
我前面说的意思是:如果班级作为聚合根对象持有小明这个聚合根对象,就会出现班级拥有小明的行为,比如小明有“跑”这个行为,那么持有小明的班级也间接具有“跑”的行为。

所以——一个聚合根绝对不能引用另一个聚合根(包括任何形式的依赖关系)。这个观点是我想出来的,理由如上,当然你可以不必理会我的结论,但是可以想一想我的理由是否正确。

当然,不经意中我自己也违反了我定的“铁律”。类图中,“学习记录”也是聚合根,却和课程有依赖关系,应当将“课程”类中的“获取未学节点ID”的参数修改为“(已学节点Id集合)”。

猜你喜欢
4Go 1 2 3 4 下一页