在尝试转向更丰富的域模型时,我们发现自己在如何最好地设计持久性层面上挣扎着.我花了很多时间阅读并思考域驱动设计模式.但是,我想要一些建议.
首先,我更有信心的事情:
>我们将在前端有“薄”控制器,只处理HTTP和HTML处理表单,验证,UI逻辑.
>我们将有一层无状态的业务逻辑服务,实现常见的算法或逻辑,不知道UI,但非常了解(和委派)域模型.
>我们将拥有一个更丰富的域模型,其中包含该域模型中的对象所固有的状态,关系和逻辑.
问题在于持续性.以前,我们的服务将通过DAO注入(通过Spring),并且将使用像find()和save()这样的DAO方法来执行持久性.然而,更丰富的域模型似乎意味着对象应该知道如何保存和删除自己,也许更高级别的服务应该知道如何定位(查询)域对象.
这里有几个问题和不确定因素出现:
>我们要将DAO注入域对象,以便它们可以在save()方法中执行“this.someDao.save(this)”?这是一个有点尴尬,因为领域的对象不是单身,所以我们需要工厂或建设后的DAO设置.从数据库加载实体时,这会变得凌乱.我知道Spring AOP可以用于此,但我无法使其工作(使用Play!框架,另一行实验),它似乎相当凌乱和神奇.
>我们是否将DAO(存储库?)完全分开,与无状态业务逻辑服务相同?这可以有所意义,但这意味着如果“保存”或“删除”是域对象的固有操作,则域对象不能表达.
>我们是否完全免除DAO,并使用JPA让实体管理自己.
这就是下一个微妙之处:使用JPA映射实体是非常方便的.表演!框架为我们提供了一个很好的实体基类,其操作类似于save()和delete().然而,这意味着我们的域模型实体与数据库结构非常紧密相连,我们正在使用大量的持久性逻辑传递对象,也许一直到视图层.如果没有别的,这将使得域模型在其他上下文中不太可用.
如果我们想避免这种情况,那么我们需要一些映射DAO – 使用简单的JDBC(或至少Spring的JdbcTemplate),或者使用数据库实体和“业务”实体的并行层次结构,DAO永远复制信息一层到另一层.
这里有什么适当的设计选择?
马丁