数据库和聚合根的存储库模式

时间:2014-02-24 09:57:26

标签: domain-driven-design repository-pattern aggregateroot

我试图理解'聚合根'的概念。

令我困惑的一件事是,我不应该直接访问子实体而不访问其聚合根。例如,假设我有一个计算机实体和一个硬件实体。

据我了解,我不应直接直接访问硬件实体。我应该通过其聚合根访问硬件实体,聚合根是一个计算机实体。

假设我有一个使用存储库并查询计算机实体的控制器。

class Controller_Test {

    public function loadHardware($computerRepository)
    {
        $computer = $computerRepository->find_by_id(1);
        $hardware = $computer->hardware; // lazy load
    }
}

如果我正在使用数据库,我将最终执行两个查询。一个用于计算机,另一个用于硬件。

在我的存储库中使用“loadComputerWithHardware”来保存查询数量是不是有意义?它是否违反了DDD规则(通过加入两个表来查询计算机和硬件)?

2 个答案:

答案 0 :(得分:4)

没有人强迫你使用延迟加载,当你有复杂的实体图时这种情况很常见,但如果它更适合你,你可以使用急切加载。请注意,即使您使用延迟加载,也可以使域模型透明。

  

让我感到困惑的一件事是,我不应该直接访问子实体而不访问其聚合根。

好的想法是聚合是唯一负责其图中所有实体的,因此,在其图中执行的所有操作都应该通过他,甚至是查询单个节点(子实体)。

  

在我的存储库中安装'loadComputerWithHardware'以保存查询数量是不是有意义?

嗯,这取决于你,但如果你不小心,你最终可能会使你的界面变得混乱。我坚持使用loadComputer并让数据存储库的每个实现决定何时更好地执行急切或延迟加载。

  

是否违反了DDD规则(通过加入两个表来查询计算机和硬件)?

不,“加入两个表”不是域概念,它是数据层关注点,它们应该解耦。

答案 1 :(得分:3)

控制器对硬件一无所知。它只知道计算机。存储库负责加载计算机所需的一切。如果从控制器的角度来看需要对硬件的引用,它可能有资格作为聚合本身。