域驱动设计,实体延迟加载

时间:2013-04-06 12:45:08

标签: php domain-driven-design

我对领域驱动设计(DDD)相当新,但我所理解的是,您与应用程序服务对话,这是您的“模型”的入口。该服务可以与使用源(文件,数据库等)来获取数据的存储库进行通信。存储库返回一个实体。

这就是我所了解的全球理念。该服务知道存储库,但不知道实体等。

现在我有以下问题。

我有一个实体用户,类似于以下内容(仅作为示例)

<?php    
class User
{
    protected $name;
    protected $city_id;

    public function getCity()
    {
         // return $city_entity;
    }
}

getCity()函数返回城市实体。我希望这个函数使用延迟加载,因此当你使用用户存储库时注入CityEntity并不是真正的延迟加载。

我带来了两个问题的解决方案。但我觉得两者都是针对DDD的原则。

我想出的第一个解决方案是在用户实体中注入城市存储库,这有一些缺点:如果您需要更多存储库,则必须在实体中加载它们。它看起来像answer但它看起来像是我的存储库的包装器。那么为什么不直接注入存储库呢?

第二个解决方案,您为实体提供服务定位器。这样做的缺点是除非您阅读代码,否则您不再需要哪些存储库。

现在,问题是,在保持DDD原则完整的同时,提供延迟加载的灵活性的最佳方法是什么?

1 个答案:

答案 0 :(得分:13)

DDD的一个主要观点是,您的域模型应该只表达有界上下文的无处不在的语言来处理业务规则。

因此,在DDD实体中,延迟加载是一种反模式。有一些原因:

  1. 如果聚合只包含确保业务不变量所需的数据,则需要它们全部且数量很少,因此eager loading效果更好。
  2. 如果你懒加载数据,你的客户必须处理那些relevant in business terms
  3. 的特殊路径
  4. 您可以使用shared identifiers来处理聚合之间的引用
  5. 使用专用查询进行投影目的(通常称为read-model
  6. 是很便宜的

    恕我直言,你绝不应该使用DDD实体作为数据访问技术:使用DTO。

    有关详细信息,您可以查看Vaughn Vernon的Effective Aggregate Design