【问题标题】:Can domain object be same as persistence object?域对象可以与持久性对象相同吗?
【发布时间】:2016-09-29 05:49:43
【问题描述】:

我们的团队有一个基本上是 MIS 的项目。 我们使用的架构是带有 DDD(领域驱动设计)的 CQRS。 我们在持久层中有持久对象,在域层中有域对象,数据传输对象用于携带来自用户的输入信息,以及在特定页面上显示数据的视图对象。

我确实认为这种设计很棒。但是在实施项目的过程中,我们发现了一些问题,让我们很受阻。最恶心的是我们要写很多转换器来实现两个不同层之间的对象转换,比如PO转DO,DO转PO,DTO转DO。这些转换器中有太多的 get 和 set 语句。我们之所以没有使用 BeanUtils 之类的东西,是因为当两个对象中的字段具有不同的类型或名称时,它就不能很好地工作。显然,这些代码违反了开闭原则。每当特定页面发生变化或我们想要更改 DB 中的字段时,这将是一场噩梦。

我想知道它是否真的必须将 DO 和 Po 分开,我们是否可以简化架构和设计以使它们相同,因为在大多数情况下它们只包含相同的字段而几乎没有区别。 我们如何简化设计以避免我们面临的问题并提高我们的生产力并确保软件的可扩展性和稳定性?

【问题讨论】:

  • 可能你有贫血的域模型。 en.wikipedia.org/wiki/Anemic_domain_model 无论如何,你不应该按照你的计划去做,因为它会导致领域模型贫乏。 ;-) 据我所知...
  • 将持久性对象与域对象分离是最近的趋势,IMO 完全是因为 ORM 在使域实体保持原始状态方面或多或少做得不好。关于映射,另请查看blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping
  • 域对象模型业务约束。持久性对象模拟数据应如何存储在数据库中。非常不同的目的。只有在简单的 CRUD 应用程序中,它们才能相同。

标签: oop domain-driven-design cqrs


【解决方案1】:

如果您查看 DDD 战术模式,您将找不到任何关于“域对象”的信息。您有由实体组成的聚合,其中一个实体是您的聚合根。每个有界上下文可能只有一个实体,这将是您的聚合根。

您将聚合作为一个整体持久化。基本存储库以“集合样式”运行,仅允许您将新聚合放入存储库并通过其身份从存储库中检索一个聚合。

CQRS 将一个对象一分为二。一个对象是您为写作而优化的聚合。通常,在“写入端”的命令处理程序中使用集合式存储库就足够了。然而,在“阅读方面”,您有更扁平的阅读模型,代表您希望以一种针对阅读进行优化的方式向用户展示的内容。

如果你说你使用CQRS但只有一个模型和一个数据库,这没有多大意义。如果您有命令处理程序,并不意味着您使用 CQRS。

在这个澄清之后,我们可以看看聚合持久性。 从来没有人说过您不能按原样保留聚合。如果您有适当的存储空间,这实际上是首选方法。通常,ORM 不是一种合适的存储,因为它会在您发现对象世界和关系数据库世界之间的阻抗不匹配的地方产生摩擦。文档数据库更适合于此。 PostgreSQL JSONB 功能也是一个不错的候选。

然后流程将是:

  • DTO(命令)从客户端发送
  • 工作单元开始
  • 命令处理程序从存储库中检索聚合
  • 命令处理程序调用聚合上的方法来执行必要的逻辑操作
  • 聚合可能会发出一些域事件,这些事件可以触发同一工作单元内的事件处理程序
  • 工作单元提交更改

如您所见,这里没有任何持久性“转换”的真正位置。如果您有适当的存储空间,一切都很好。

但是,当您阅读时,您会收到来自客户端的请求。然后,此请求将发送到某个查询提供者、数据提供者或您所称的任何东西。有些人将所有这些查询放入他们的存储库中,但这仅在您使用 CQRS 或至少有一个持久性模型而不是两个时才有效。

查询是幂等的,它们不会改变系统的状态,并且可以根据需要运行多次而不会产生任何后果,除非如果未优化读取,则可能会加载持久层。但是,没有必要在读取端放置大量抽象。同时,您不应将聚合发送回查询您的域的客户端。您需要有一个 DTO 来代表特定需求的客户端视图模型,而不是更少也不是更多。此 DTO 需要优化以尽可能快地在客户端呈现,无需计算和转换。这基本上是 CQRS 建议在您的读取端执行的操作 - 准备您的数据以快速交付这些 DTO。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多