2

我有一个关于领域驱动设计的问题。让我们想象一个简单的场景。

我有一个名为“用户”的实体,它有一些属性。这些属性之一是“date_created”、“date_modified”和“last_login_ip”。

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

  1. 控制器获取 POST 数据
  2. 通过“createAndAuthenticateUser”方法将发布数据发送到 UsersService
  3. 服务接收数据并对其进行验证(在此处进行而不是在实体中进行,因为验证与存储库相关联,例如验证电子邮件是否已经存在等)。
  4. 如果验证成功,它会创建一个新实体,将数据分配给它,然后将实体发送到存储库以保存它。然后,存储库将此用户保存在数据源中。

到现在为止还挺好。这里的问题是,必须在此服务方法中设置 date_created/date_modified/last_login_ip。

如果我想在用户对象更新时随时设置 date_modified 怎么办(例如,登录时我想更新 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 属性。但同样,这意味着必须从多个地方调用此方法,而不是有一个集中的地方来执行此操作。我看不到在存储库中没有此代码的好处。

有任何想法吗?

4

1 回答 1

0

如果出于某种原因,上次登录 ip 的概念实际上对您的用户至关重要,那么在登录时更新用户是有效的。您对执行该更新以保存上次登录 IP 表示关注这一事实意味着它不是真正的用户概念,而是安全、审计或其他外部用户概念。

As for setting the modify and create dates, I'd make the same argument. If it's a requirement of the system that the user both maintain and expose that information, then create a private method on the user that each public method calls when it modifies the state, which will set the modify date. If it's not, then you pretty much have two options - either create an auditing service that is notified of the update and keeps its own audit record, or have the repository set the fields when it updates the record.

于 2012-08-01T13:41:20.013 回答