我正在使用ORM重新建模一个现有的应用程序,并尽可能地坚持DDD。
工作订单是AR,有十几个子实体。我打算对这个类建模如下:
class WorkOrder {
private $number = 0;
private $manual = '';
...
// Sub-Entities
private $consumables; // Collection (1:m)
private $dimensions; // Collection (1:m)
private $sequences; // Collection (1:m)
...
}现在我需要一个存储库来加载(并且持久化?)这个聚合根-对吗?
回购将返回一个或多个聚合,当我访问子实体(通过间接的getter/getter-而不是点符号)时,会延迟加载我想要的信息吗??
我将有另一个类作为工厂来创建工作订单--这是一个详细的过程,包括大量的业务逻辑/验证规则.
但是,如果工厂创建了工作订单聚合,那么回购是否只是持久化AR?
这个工厂必须查询第三方服务(通过REST或其他方式),并且基本上构建一个描述工作范围的已批准文档的快照。
因此,存储库封装了ORM,或者我应该选择哪一个持久化层?
现在,我的文件结构应该如下所示:
WorkOrder/
/Factory.php
/Aggregate.php
/Repository.php
/Entity/Header.php
/Entity/Shipping.php
/Entity/Warranty.php
/Entity/Certification.php
...存储库将具有如下方法:
FindOneByTrackingNumber()
FindAllByCriteria()
save($root);我的工厂会有这样的方法:
createWorkOrderFromRpi()
createWorkOrderFromCsv()
...我在这里读过几篇文章和无数的帖子:
http://williamdurand.fr/2013/08/07/ddd-with-symfony2-folder-structure-and-code-first/
虽然细节很好,但我需要一个关于我自己的解释的第二种意见。:)
你好,亚历克斯
发布于 2014-06-22 08:50:23
原则不适合DDD。它不能处理深度域对象关系。我认为没有任何ORM能够很好地映射对象,而无需编写大量注释或映射元数据。如果您正确地构建域模型,那么ORM是无用的。
您需要考虑DDD的一个基本规则:每个聚合一个事务。考虑到这个规则来设计您的域模型也将有助于您实现持久化。您甚至会意识到您不再需要关系数据库了。即使使用RDBMS,也会帮助您实现可伸缩性。
是的,99%的案例中的存储库用于持久化域对象。存储库应该处理映射(而不是ORM ),这些映射将通过使用数据反射(域对象不应该关心的方法)自动填充域对象。
在存储库中创建自己的映射(简单属性db表列映射)在移除和保存聚合时并不困难。问题是更新聚合,但问题不是映射,而是跟踪域对象的状态变化。但同样,这并不是一个映射问题,而是一个工作单位。
现在我需要一个存储库来加载(并且持久化?)这个聚合根-对吗? 对,是这样。存储库持久化域状态更改,并重新构成域的状态。回购将返回一个或多个聚合,当我访问子实体(通过间接getter/getter-而不是点符号)时,这些聚合将延迟加载我想要的信息??。 是的,您可以使用getter(如果您使用域模型填充UI,选择cqrs,您可以使用域模型来跟踪域的状态)。你不应该有设置器,你应该只有改变状态的方法,这些方法反映了无处不在的语言(changeName,addItemToCart)。延迟加载是有用的,只是为了节省一些内存。如果内存不是问题,您还可以对域对象的最新状态进行快照。是的,延迟加载是ORM的工作,它迫使您在域对象中有某种类型的getter,这是DDD的一个很大的限制。
,但是如果工厂创建了工作订单聚合,那么回购只会持久化AR?。
工厂在您的域中创建新的状态。存储库重新构成曾经由工厂创建的状态。
,所以存储库封装了ORM,或者我应该选择哪一个持久层?。
是的,存储库应该处理域状态的重构。奥姆只是一个技术问题,只是一个图书馆。无论如何,ORM是公共库/共享内核层的一部分,存储库是基础结构层的一部分。
关于您的文件结构,您应该阅读更多关于DIP、IOC、DDD有界上下文的内容。这将帮助您基于组件构建应用程序,并将组件解耦到可伸缩的应用程序中。
https://stackoverflow.com/questions/18835117
复制相似问题