Domain driven design 存储库模式会杀死ORM吗?

Domain driven design 存储库模式会杀死ORM吗?,domain-driven-design,orm,repository-pattern,Domain Driven Design,Orm,Repository Pattern,除了将关系数据转换为对象模型外,ORM还有其他作用,如: 延迟加载 自动变化检测 交易 但是,使用存储库模式将ORM的DTO转换为域模型,会发生以下情况: 无法利用延迟加载的好处,因为我需要填充整个域模型,存储库不知道data Domain需要什么 ORM无法检测到更改,因为域模型不是来自ORM世界 由于缺乏关于ORM 问题1:我是否遗漏了一些差距,在这些差距中,我可以在场景中充分利用延迟加载、事务和自动更改检测的好处?或者这些好处更多地用于另一种方法(如活动记录)而不是DDD 问题2:为什么在

除了将关系数据转换为对象模型外,ORM还有其他作用,如:

  • 延迟加载
  • 自动变化检测
  • 交易
  • 但是,使用存储库模式将ORM的DTO转换为域模型,会发生以下情况:

  • 无法利用延迟加载的好处,因为我需要填充整个域模型存储库不知道data Domain需要什么
  • ORM无法检测到更改,因为域模型不是来自ORM世界
  • 由于缺乏关于ORM
  • 问题1:我是否遗漏了一些差距,在这些差距中,我可以在场景中充分利用延迟加载、事务和自动更改检测的好处?或者这些好处更多地用于另一种方法(如活动记录)而不是DDD

    问题2:为什么在DDD书籍中如此提及?仅就关系到域模型和延迟加载而言,事务和更改检测是完全讨论的


    一些平台采用代码优先的方法,这是一种改善这些问题的方法,但是这种功能在许多环境中并不总是存在,或者根本无法使用(例如在遗留数据库中),因此,这不是一个解决方案。

    我一直在想,如果从ORM中删除更改跟踪,那么开发人员会发现它们的价值要小得多

    延迟加载永远不会发生。骨料始终以整体形式装载。如果您发现自己需要延迟加载,那么很可能您正在查询您的域模型。这是你不应该做的事。为此,请使用简单的查询层/读取模型

    事务确实是DB关注的问题,不会直接影响DDD。聚合确实表示一致性边界,因此数据库事务是自然匹配的,但这就是它的结束

    您仍然可以将ORM工具与DDD一起使用,但您可能会获得更少的里程数。我一点也不喜欢ORMs,如果我在这件事上有任何选择,我就是不使用它们。映射实际上并不是那么多的工作,如果在自定义映射器类中完成映射,它将以语言速度运行,而不是以某种代理机制运行

    我见过一些实例,例如,使用ORM直接持久化域对象。然而,如果我必须使用(比如)属性标记任何东西,或者甚至更改我的设计,其中我必须将某些方法实现为
    virtual
    ,或者甚至以特定的方式构造某些类,那么我不再认为我的域是永久无知的,这是我真正想要的(PI)

    为什么在DDD书籍中提到ORM?只是为了让关系 域模型和延迟加载、事务和更改检测 全神贯注

    您可以在中的蓝皮书中找到货物系统的DDD实现。它使用Hibernate作为ORM

    应用程序服务中存在数据库事务,例如,请参见
    se.citerus.dddsample.application.impl.BookingServiceImpl
    @Transactional
    是来自Spring的注释,它导致方法被包装到数据库事务中

    更改检测不会被丢弃。原始DDD模式中的存储库没有更新方法,因此使用更改检测(ORM)来更新域对象。例如:

    @覆盖
    @交易的
    公共无效分配货物路线(最终行程,最终跟踪ID跟踪ID){
    最终货物=cargoRepository.find(trackingId);
    如果(货物==null){
    抛出新的IllegalArgumentException(“无法将行程分配给不存在的货物”+trackingId);
    }
    货物分配路线(行程);
    货物储存库。仓库(货物);
    logger.info(“指定货物”+跟踪ID+“到新路线”);
    }
    
    实际上,在示例中,存储库有更新方法,因为
    cargoRepository.store()
    是更新方法:

    公共仓库(货物){
    getSession().saveOrUpdate(货物);
    //当父对象是组件时,“删除孤立对象”似乎无法正常工作
    getSession().createSQLQuery(“从cargo_id=null的分支删除”).executeUpdate();
    }
    
    令人惊讶的是,您可以在官方示例中找到惰性集合的用法,例如在src/main/resources/se/citerus/dddsample/infrastructure/persistence/hibernate/Cargo.hbm.xml中:

    
    ...
    
    因此,答案是您仍然可以享受ORM的所有好处

    然而,使用存储库模式将ORM的DTO转换为域 模型,即:

  • 无法使用延迟加载的好处,因为我需要填充整个域模型,而存储库不知道数据域是什么 需要
  • ORM无法检测更改,因为域模型不是来自ORM世界
  • 由于缺乏关于ORM的领域知识,无法同时执行许多事务
  • 使用现代ORM时,无需实现另一层将ORM实体映射到域实体。在.NET世界中,实体框架或NHiberate都能够将您的富域模型映射到关系数据库中

    代码优先方法可用于这两种方法

    首先设计域模型,然后使用映射(/)或约定(/)生成数据库

    有一些相关的问题:


  • 谢谢你,埃本!现在我有另一个问题,为什么在DDD书籍中提到ORM?仅针对关系域模型?而延迟加载、事务和更改检测只是剩下的?在使用