【问题标题】:pure Domain Driven Design in PHP project [closed]PHP项目中的纯领域驱动设计[关闭]
【发布时间】:2016-01-05 15:52:03
【问题描述】:

在“PHP World”中,我能找到的任何 DDD 应用程序(示例)中的基础设施层都有一种奇怪的感觉。

我看到很多例子,当开发人员在基础设施层使用Doctrine2时,使用域实体(来自域层)作为Doctrine2模型,将doc cmets放在上面,或者在config(xml,yml)中提及它们. 例如,Big Blue Book example,这是域实体所在的位置:https://github.com/codeliner/php-ddd-cargo-sample/tree/master/CargoBackend/src/Model,您可以看到它与 Doctrine 高度耦合(查看注释)。是吗?

我觉得这是错误的方式。

我对 DDD 的理解是: 存储库应查询持久层并将结果传递给工厂以正确实例化Aggregate Root 实体(域模型)。这意味着只有 Factory 知道如何实例化特定的 Aggregate Root,此外还有一个所谓的实体生命周期。这意味着并非每次域实体都应通过__construct 实例化(水合)。

如果我有正确的感觉,那么在类似 DDD 的应用程序中正确使用 Doctrine2 的好例子在哪里?

【问题讨论】:

    标签: php symfony domain-driven-design onion-architecture


    【解决方案1】:

    Tbh 我不完全理解你的问题,但我会尽力回答。

    领域层中的 ORM

    ORM is best way to easily map your domain objects to your database layer.事实上,它使用您的域模型并不会使其与您的聚合和实体耦合。 People are scared,他们需要有干净的域层,这就是人们喜欢通过 xml、yml 映射他们的域层的方式。我会说feel free to map it by annotations,如果你确定,那you're not going to change orm framework in the future。这将帮助出现在您位置上的开发人员轻松更改映射。在 PHP 中,您可以肯定,该学说将在很长一段时间内排名第一,所以请随意使用它。

    但在使用 ActiveRecord 时要小心,因为它确实将您与框架结合在一起。如果您不想使用 ORM,则需要使用干净的 sql 映射。如果你有复杂的域名,祝你好运:)

    不要害怕耦合

    如果您觉得PHP lack features 并且它们应该在原生 php 中构建,请随时在您的模型中直接使用它们。例如,我使用 Doctrine ArrayCollection 作为模型的一部分,因为如果我使用 Java,例如,我将直接在语言中使用 Collections 类型。只是PHP is retarded with some features,我们需要帮助它一点;)
    框架也是如此,无论如何您都可能会在域层中实现它,例如用于事件溯源的 Broadway。

    不要与你的框架作对

    有时您会发现,您使用的框架(例如 ORM one)不允许您按照您的意愿执行操作。你已经选择了框架,如果你不想改变它,就不要抗拒它。你需要接受它的所有优点和缺点。

    阅读 Vaughn Vernon 的红皮书

    我发现您不太了解构建块。 工厂负责在其生命周期开始时构造对象。 存储库负责保存状态并从数据库中检索它。 你应该先从红皮书开始,它有很多例子。我认为它对 DDD 初学者比 Blue Book 更友好。

    【讨论】:

    • 感谢您的回复。从我正在阅读的内容来看(这是 mixin 中的蓝色和红色书籍),工厂会很好,不仅仅是它们生命周期的开始。但也用于恢复实体。我也使用ArrayCollection,这不会让我更害怕。对我来说,主要问题是什么其他“世界”使用:) C#Java。他们是否在 NHibernate、EntityFramework 中使用域实体作为 ORM 模型?
    • 只要你用 ORM 映射你的模型,你的工厂只用于创建新对象。通过 Repository 从 ORM 检索域对象然后将其推送到工厂是没有意义的。 ORM 将重建您的整个聚合,那么您要向工厂推送什么? :) Java 用户也使用 ORM,如果它对您很重要,Doctrine 是基于 Hibernate。看看这个项目:github.com/BottegaIT/ddd-leaven-v2
    • 澄清一下,我有一个域模型,它需要一些特定的数据作为构造函数方法中另一个表的对象。 Doctrine 会注入所有这些依赖项吗?为什么需要工厂?因为 Repository 不应该知道如何构建实体对象。这不是存储库的责任。附:我说的是面向集合的存储库。
    • 那么存储库的职责是什么? :) 存储库应该隐藏域层的持久层。它应该返回聚合并保存聚合,但不要在它们的生命周期开始时构造它们。如果您不使用 ORM,您可能会从数据库中检索数据并将其推送到某种重构工厂,但我们在这里谈论的是 ORM,对吧? :) 学说会处理具有实体集合的聚合吗?这是关系数据库中的常见问题。我不会在这里谈论它,因为它是另一个主题的主题。
    • 您需要了解的有关 ORM 映射的一切都在这里leanpub.com/ddd-in-php
    猜你喜欢
    • 2010-09-11
    • 2010-09-14
    • 2010-11-16
    • 2010-10-06
    • 2011-10-06
    • 2010-12-17
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多