您在DDD中将常用数据设置器放在何处进行更新/插入?

时间:2012-08-01 13:07:41

标签: php service repository domain-driven-design

我对域驱动设计有疑问。让我们想象一个简单的场景。

我有一个名为“User”的实体,它有一些属性。其中一个属性是“date_created”,“date_modified”和“last_login_ip”。

假设我们有一个创建用户的表单,如果创建成功,它会对他进行身份验证。

  1. 控制器获取POST数据
  2. 通过“createAndAuthenticateUser”方法将发布数据发送到UsersService
  3. 服务接收数据,验证数据(在此处执行,而不是在实体中执行,因为验证与存储库相关联,例如验证电子邮件是否已存在等)。
  4. 如果验证正常,它会创建一个新实体,将数据分配给它,然后将实体发送到存储库以保存它。然后,存储库将此用户保存在数据源中。
  5. 到目前为止一切顺利。这里的问题是,必须在此服务方法中设置date_created / date_modified / last_login_ip。

    如果我想在更新用户对象时设置date_modified ANYTIME怎么办?例如,在登录时我想更新date_modified,在用户更新时我又想要它,在创建用户时我又想要它。

    从逻辑上讲,我自己的答案是将其放在存储库中,如...

    (元代码在这里排序,语法无关紧要)

    function save($User) {
    
    if (!$User->id) $User->date_created = 'YYYY-MM-DD HH:II:SS';
    
    $User->date_modified = 'YYYY-MM-DD HH:II:SS';
    
    $DataSource->Save($User);
    
    return $User;
    }
    

    然而,根据我一直在阅读的内容,存储库应该始终只是在调用者和数据源之间映射数据(反之),就是这样。它永远不应该设置数据或类似的东西。

    当然,你可以告诉我这是一种行为,所以我可能会有一个行为,上面写着$ User-> markAsUpdated(),它只会设置date_modified属性。但同样,这意味着必须从多个地方调用此方法,而不是集中处理它。我没有看到在存储库中没有此代码的好处。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

如果上次登录ip的概念由于某种原因实际上是您的用户的核心,那么在登录时更新用户是有效的。您对执行该更新以保存上次登录IP表示担心的事实意味着它不是真正的用户概念,而是安全性,审计或其他 - 外部到用户的概念。 / p>

至于设置修改和创建日期,我会使用相同的参数。如果系统要求用户同时维护和公开该信息,则在用户创建一个私有方法,每个公共方法在修改状态时调用该方法,这将设置修改日期。如果不是,那么您几乎有两个选择 - 创建一个审核服务,通知更新并保留自己的审核记录,或让存储库在更新记录时设置字段。