Jivedon3.0站内消息设计的疑惑。

banq老师您好。今天看了下jivedon3.0源代码,对于站内消息的设计有以下疑惑,请老师解答,谢谢。
第一:关于ShortMessageRepository与ShortMessageFactory的职责问题。
我觉得ShortMessageFactory不应该ShortMessageDao关联,我觉得factory只负责创建新建的消息,以及要保存到草稿箱的消息,只需要保证消息的不变量得到满足,不需要保存消息。相反应该让ShortMessageRepository通过factory来生成出满足不变量约束的消息,然后ShortMessageRepostiory再调用dao去保存消息。不知道这样是否妥当。
第二:关于ShortMessageService与ShortMessageRepostiory的职责问题。
我觉得ShortMessageService的判断接收者是否是论坛用户的操作,应该放到仓库中,因为仓库是管理对象生命周期的地方,所以仓库应该保证消息的合法性,让仓库去判断消息的接收者是否合法。服务只是调用仓库去完成工作,至于领域对象的合法性交给仓库。
第三:站内信删除的问题。
当删除站内信的时候,只要是接收者或者是发送者就可以删除,那么如果发送者发送完消息后,再删除消息,那么接收者就没有机会看消息了,所以我觉得应该再设置两个字段,一个判断接收者同意删除,另一个判断发送者同意删除。当删除消息的时候,只有这个条件都为真的时候才删除。

这些是我看jiveDon的一些疑问,还请老师帮忙解答。谢谢了。
[该贴被xmuzyu于2008-09-01 22:04修改过]
[该贴被admin于2008-09-22 10:55修改过]

没好好看过源码,从描述来看,第二个应该是由领域层次判定合法性,不是服务也不是rep
第三个的删除应该做成删除策略,有能力选择一种进行删除。

前些时候也看了站内消息这一部分.

factory与repository的作用,都是让我们能在对象的世界,摒除数据库的影响.
factory就是创建对象
reposiory是对象仓库,管理着对象的进进出出
两者结合使用.
所以感觉不管是哪个都可以去调用DAO,构建完整的对象.
创建对象时,最好是repository-->factory-->dao
现在的jivejdon3,没有这样,我认为也无防,关键我们从上层看不到DAO的影子,一切都是对象.
当然,具体的说明还得banq出马.


>>>>判断接收者是否是论坛用户的操作
我认为这是应用服务,放在service里,很合理.

对于第三点,这应该是个BUG,不知道banq认同不?呵呵.


仓储是对象和存贮间转换的东西,为了表示“对象已经在那里了”这种概念,是个重新载入的过程而不是创建过程。其实如果对象一直都在那里,就用不着仓储了。从实际生活中的意义来说,创建了就不用保存了,它就在那了,但是计算机是需要保存的,所以仓储应该也负责保存的功能。
工厂是封装聚合根的创建的东西,聚合根创建的时候不是造出来它自己就完事了,它要有很多其它与它关联的东西要一并建出来,工厂是建对象的东西,它相当于扩展的new,至于对象建出来之后干了什么事,到哪里去了,它都不用管,比如一个皮包工厂造了一批皮包,只有物流知道它去哪了,最后的客户知道用它装什么东西,知道它坏没坏,而这些皮包工厂是没有责任去负责的。

各位意见都很合理,短消息这块因为大家合作开发,没有仔细认真去考虑,主要从简单入手。

楼主提的ShortMessageFactory和DDD中提的工厂有些不太一样,你是业务上的工厂,楼上freebox意见可参考。

>因为仓库是管理对象生命周期的地方,所以仓库应该保证消息的合法性
我不认为这两句存在前后因果关系,仓库和工厂一起来保证对象的生命周期,但是这与具体当前业务上消息是否合法应该无关。

第三个问题属于需求问题,需求上按你要求则比较完善,这也有争论:发出的消息如果发送者后悔了,不管对方是否看过,就删除,不想让对方看到,也是符合情理。

多谢各位解答疑惑。
比如一条消息,如果它的接收者不是论坛用户的话,那么这个消息就不满足完整性约束,而判断到底消息是否满足完整性约束(即消息接收者要是论坛用户)的职责应该放哪里呢?放到服务?还是放到仓库?还是其他地方?
jivedon是将其放到了服务中.

jivedon中的ShortMessageFactory不仅创建了满足约束消息,而且还调用dao保存了消息,我以前的理解是,仓库可以和dao共存的,dao只负责数据库的操作,至于它操作的数据合法不合法,约束满足是否,都不管,而把这些职责留给工厂和仓库,不知道是否理解正确。还请各位帮忙。

假设创建消息的工厂Factory接口是这样的:
Message create(Member to,Object[] otherObject);
那么这里面其实包含了一条业务规则是to必须是论坛用户。于是创建一个规则,包含一个验证


interfact MemberRule{
boolean canBeUse();
}
class IsForumMember implements MemberRule{
boolean canBeUse(Member m){
return false;
}
}

由于创建出来的消息必须满足一批规则,所以应该有

class MemberFactory{
List<MemberRule> rules;
//MemberFactory(){}
//MemberFactory(List<MemberRule> r){
// this.rules=r;
//}
//发现拿着构造方法注入规则表不太合适
public void setMemberRules(List<MemberRule> rules){
this.rules=rules;
}
Message create(Member to,Object[] otherObject){
for(MemberRule r:rules){
if(!r.canBeUse(to)){
throw new MemberCanNotBeUseException();
}
}
//do create
}
}

这时候IsForumMember完全负责了“是否是论坛用户”的规则表达,还可以有其它一些表达,比如说不准用户名是"freebox"的人接收消息,那么对他发消息也没用了,这也可以建个Rule
[该贴被freebox于2008-09-02 20:47修改过]

分析的有道理。那就是说工厂都通过规格去验证对象的合法性。把规格抽象出去了,不错呵呵。

>职责应该放哪里呢?放到服务?还是放到仓库?还是其他地
>方?jivedon是将其放到了服务中.

应该在领域层,属于业务核心部分,freebox使用spec来实现是有道理的,在JiveJdon中放到服务看来不确当的,这部分是一位JiveJdon开源开发者开发的,我也没有仔细去审核重构这部分。

哦多谢。那应该和我的理解是一致的。多谢各位了。

谢谢大家讨论,消息是我做的。
因为对DDD了解不是很深刻,做的不好,希望大家能理解。
对于删除消息,那块,确实是我没做好。:)
我也只是抛砖引玉,大家说的都很有道理,其实开源的目的就在于大家可以参与进来。希望大家都能够参与其中。:)
[该贴被xinying_ge于2008-09-03 22:04修改过]

freebox很佩服你: )

是啊,freebox很厉害呀,希望加入jivejdon给我们带来赏心悦目的代码!!