sem*_*ral 19 java oop spring design-patterns domain-driven-design
我曾经围绕贫血领域模型设计我的应用程序,因此我有许多存储库对象,这些对象被注入到大的,胖的,事务感知服务层.此模式称为事务脚本.它不是一个好的做法,因为它导致了程序代码,所以我想继续前进到域驱动设计.
在网上阅读了几篇文章后,听了Chris Richardson关于Parleys的演讲并阅读了POJO in Action的DDD章节,我想我已经了解了全局.
问题是,我不知道,如何在我的应用程序中组织事务.Chis Richardson在他的书中指出:
表示层通过直接或间接通过façade调用域模型来处理来自用户浏览器的HTTP请求,正如我在前一章中描述的那样,它是POJO或EJB.
好到目前为止,但InfoQ上的Srini Penchikala 文章指出:
一些开发人员更喜欢在DAO类中管理事务,这是一个糟糕的设计.这导致过于细粒度的事务控制,这不能提供管理事务跨越多个域对象的用例的灵活性.服务类应该处理事务; 这种方式即使事务跨越多个域对象,服务类也可以管理事务,因为在大多数用例中,Service类处理控制流.
好的,所以如果我理解正确的话,存储库类不应该是事务性的,服务层(现在更薄)是事务性的(因为它曾经是在事务脚本模式中).但是如果域对象直接被表示层调用呢?这是否意味着我的域对象应该具有事务行为?以及如何在Spring或EJB环境中实现它?
这对我来说似乎有些奇怪,所以如果有人澄清这一点,我会很高兴.谢谢.
看到这个非常有用的博客文章.它解释了如何在不失去Spring和JPA功能的同时实现平滑的DDD.它以@Configurable注释为中心.
我对这些问题的看法有点不受欢迎.贫血数据模型实际上没有错.您没有一个带有数据+操作的对象,而是有两个对象 - 一个包含数据,另一个包含操作.您可以将它们视为一个对象 - 即满足DDD,但为了更容易使用,它们在物理上是分开的.逻辑上它们是一样的.
是的,这打破了封装,但它不会让你使用一些'魔术'(aop + java代理)来实现你的目标.
至于交易 - 有一种称为交易传播的东西.Spring支持它@Transactional(propagation=Propagation.REQUIRED).
见9.5.7.如果您希望事务跨越多个方法(多个对象),则可以相应地更改传播属性.
您也可以@Transactional在适当的时候在服务层中使用,但是如果您想使用简单的单步操作(如"save"),这可能会引入很多样机服务类.