存储库中聚合对象的正确重构?
假设存储库内没有使用 ORM(例如 Doctrine),我的问题是实例化聚合对象的正确方法是什么?是直接在存储库内实例化子对象,然后通过其设置器将其分配给聚合根,还是聚合根负责构造其子实体/对象?
示例 1:
class UserRepository
{
// Create user domain entity.
$user = new User();
$user->setName('Juan');
// Create child object orders entity.
$orders = new Orders($orders);
$user->setOrders($orders);
}
示例 2:
class UserRepository
{
// Create user domain entity.
$user = new User();
$user->setName('Juan');
// Get orders.
$orders = $ordersDao->findByUser(1);
$user->setOrders($orders);
}
而在示例 2 中,订单的实例化是在用户实体内部进行的。
Assuming that no ORM (e.g. Doctrine) is used inside the Repository, my question is what is the proper way of instantiating the Aggregate objects? Is it instantiating the child objects directly inside the Repository and just assign it to the Aggregate Root through its setters or the Aggregate Root is responsible of constructing its child entities/objects?
Example 1:
class UserRepository
{
// Create user domain entity.
$user = new User();
$user->setName('Juan');
// Create child object orders entity.
$orders = new Orders($orders);
$user->setOrders($orders);
}
Example 2:
class UserRepository
{
// Create user domain entity.
$user = new User();
$user->setName('Juan');
// Get orders.
$orders = $ordersDao->findByUser(1);
$user->setOrders($orders);
}
whereas in example 2, instantiation of orders are taken care inside the user entity.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您绝对应该使用构造函数来创建对象,而不是设置器。 DDD 的重要原则之一是沟通意图。如果需要名称才能创建用户,那么您可以通过只允许在提供名称的情况下创建 User 实例来清楚地传达该要求。这些称为“不变量”,在创建对象之前应始终满足这些条件。这样,您就可以清楚地表达“这是您在该对象处于有效状态之前需要提供的内容”。
当重构一个对象(例如在存储库中)时,您需要将子对象传递到构造函数中。根据我的经验,我的聚合有 2 个构造函数:一个用于创建(可能由工厂调用),一个用于重构(通常由存储库调用)。
You definitely should be using the constructor to create objects, not setters. One of the important principles of DDD is communicating intent. If name is required in order to create a user, then you communicate that requirement clearly by only allowing a User instance to be created if a name is supplied. These are called "invariants" and should always be satisfied before an object is created. This way you are clearly saying "this is what you need to supply before this object is in a valid state."
When reconstituting an object (e.g. in a repository), you'll want to pass the child objects into the constructor. In my experience, my aggregates have 2 constructors: one for creation (possibly called by a factory), and one for reconstitution (typically called by a repository).