关于业务规则

按照对DDD的理解,一般使用规约模式实现内禀的业务规则。但有些业务规则可以体现为对其他聚合的查询。
而对仓储的调用一般都放在应用层,而这样会造成部分业务逻辑散落在应用层。请问大家有没有好的办法处理?

附上一个订单系统例子,当用户提交订单后,应用层的处理流程如下:

1、开启一个事务
2、调用account的仓储按照account id查询并返回相应的account对象
3、调用Order的工厂方法,创建一个新的Order对象
4、调用下单的业务方法并将account与order对象传进去
5、该方法返回成功后,保存并提交。结束事务。

以上过程中,下单相关的检查(业务规则)一般写在业务方法或order的工厂方法中(使用规约模式? or not)

现在我们新增一些业务规则,1、下单时需要检查要购买的商品是否有货 2、按该商品的类型检查是否享受折扣
增加之后,应用层的处理流程改变如下:

1、开启一个事务
2、调用account的仓储按照account id查询并返回相应的account对象
3、调用商品的仓储按照商品名或id查询并返回相应的商品对象
4、调用折扣信息的仓储按照该商品的类型查询并返回布尔值
5、调用Order的工厂方法,创建一个新的Order对象
6、调用下单的业务方法并将account与order对象传进去
7、该方法返回成功后,保存并提交。结束事务。

从以上例子来看,这些可以使用仓储条件查询实现的业务规则如何放到Domain层去?有没有好的方法可以提高?谢谢!
[该贴被admin于2014-05-09 06:23修改过]

首先要确定Order是聚合根,那么业务规则应该封装在聚合根所在的聚合中,也就是说规约模式是属于一个聚合的。

上面的步骤前后调整一下:
原来是:
3、调用商品的仓储按照商品名或id查询并返回相应的商品对象
4、调用折扣信息的仓储按照该商品的类型查询并返回布尔值
5、调用Order的工厂方法,创建一个新的Order对象
6、调用下单的业务方法并将account与order对象传进去

调整为:
3、调用Order的工厂方法,创建一个新的Order对象
4、调用Order的下单的业务方法并将account与order对象传进去
5. Order的下单方法中,首先执行下单前业务规则检查,也就是规约模式,将业务规则检查(可以使用SQL这样的DSL)发消息给仓储层。
6、调用折扣信息的仓储按照该商品的类型查询并返回布尔值消息给Order。

你的意思是规约方法可以直接调用仓储层么?但是规约是写在Domain层的,这样是否不符合DDD的思路?

还是说规约返回查询条件?然后在应用层传递给仓储?

2014-05-09 11:47 "@lxitgto"的内容
规约方法可以直接调用仓储层么 ...

请注意,我上贴写了"发送消息或事件驱动"仓储层做事。

领域层和仓储层之间一定要有事件或消息框架支持,否则领域层无法命令仓储层做事,因为不能直接调用,也不能通过应用层调用仓储层。

2014-05-09 14:09 "@banq"的内容
领域层和仓储层之间一定要有事件或消息框架支持,否则领域层无法命令仓储层做事,因为不能直接调用,也不能通过应用层调用仓储层。 ...

怎么又出现了仓储层,现在很多无良架构硬生生的定义一个仓储实现层,而实际上,Entity,ValueObject,Service,Factory,Repository都是DDD的经典元素,自古以来都属于领域层,是领域模型中不可分割的一部分(这话点耳熟)

对于规约,在DDD中只用来验证、过滤与构建对象,处理业务规 则还差一点,还得靠“workflow”!
但对workflow与ddd之间关系处理,其实也是比较尴尬!DDD新闻组感觉也是没讨论出一个所以然来!!

我来重新讨论这个问题,按照《实现领域驱动设计》书中提到的方式是封装在领域服务中。楼上两位是否同意?