1

我有一个问题是如何更好地组织以下功能的实现。假设用户需要通过唯一的电子邮件和密码注册到系统(第一步),然后他应该确认注册(第二步)。我有几种选择在应用程序服务/域服务/用户实体之间构建第一步(注册)的实现,我不确定哪个更好。

第一个选项:

应用服务:

var existingUser = UserRepository.GetUserByEmail(email);

if (existingUser != null)
{
    throw new ValidationException(...);
}

var newUser = UserFactory.CreateUser();

newUser.Register(email, password);

UserRepository.Save(newUser);

// commit

所以在这里,我们不使用任何域服务。我个人觉得不舒服的是,在应用程序服务中检查了电子邮件唯一性业务规则,这是一个业务规则。

第二种选择:

应用服务:

var user = UserRegistrationDomainService.RegisterUser(email, password);

UserRepository.Save(user);

// commit

用户注册域服务:

User RegisterUser(email, password)
{
  var existingUser = UserRepository.GetUserByEmail(email);

  if (existingUser != null)
  {
    throw new ValidationException(...);
  }

  var newUser = UserFactory.CreateUser();

  newUser.Register(email, password);

  return newUser;

}

我不喜欢这里的是,这个解决方案与第二步的实现不太对称,我们只是从存储库中获取用户并调用 User.ConfirmRegistration()。因此,对于注册确认,我们不需要任何域服务,而对于注册,在第二种选择中,我们使用此类服务​​。

哪个选项更好?第一个选项的应用程序服务是否可以包含电子邮件唯一性验证?

4

2 回答 2

2

就我个人而言,我认为验证存在于域中(服务的实体)。毕竟,由于业务规则,规则是必需的。

在选项 2 中,应用程序服务最好不负责保存用户,这会模糊职责范围,如果域服务处理它会更好。并且应用程序服务会简单地调用UserRegistrationDomainService.RegisterUser(email, password)

于 2012-05-30T07:21:56.383 回答
1

选项 1 表示唯一电子邮件规则是特定于应用程序的。换句话说,如果您将 Domain dll(或 jar、模块等)在另一个应用程序中重用,则该规则将不再存在。

由于我们可以合理地认为该规则与应用程序无关,因此我会选择选项 2。

另一种解决方案可能是在工厂中实现它。毕竟,这是您通常在创建用户时放置验证逻辑的地方(空/空名称检查、电子邮件格式验证等),那么为什么不将所有创建规则集中在同一个地方呢?

于 2012-05-30T12:15:58.260 回答