存储库应该引发域错误 [英] Should Repositories Throw Domain Errors

查看:50
本文介绍了存储库应该引发域错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个尝试遵守干净架构的应用程序.我了解该存储库旨在抽象化持久层并根据域语言返回实体.但是,这是否意味着它也应该在出现问题时检查并引发域错误.让我们考虑一下我想通过用户存储库添加用户的情况.我可以执行以下操作:

I am building an application that tries to abide by clean architecture. I understand that the repository is meant to abstract away the persistence layer and return back entities in terms of the domain language. But, does that mean that it is also supposed to check and throw domain errors if something goes wrong. Let's consider a situation where I want to add a user via the user repository. I can do the following:

// in user repo
const add = (user: User): void => {
  try {
    // do some database stuff
  } catch() {
    throw new EmailAlreadyInUse(user.email);
  }
}

但是这种实现是明智的吗?现在,我们依靠数据库正确地设置了正确的唯一密钥架构来实施域规则(没有两个用户可以使用同一封电子邮件进行注册).在我看来,这似乎是我们可能将域规则泄漏到外围站点层.

But is this implementation advisable? We are now relying upon the database to have been setup correctly with the correct unique key schema to enforce a domain rule (no two users can register with the same email). This seems to me like we are potentially spilling domain rules to the perisitence layer.

从用例层中代替抛出此异常会更有意义.

Would it make more sense to throw this exception from the use case layer in stead.

const AddNewUserUseCase = (userRepository, email) => {
  const user = userRepository.findByEmail(email);
  if(user) {
    throw new EmailAlreadyInUseError(email)
  }
  else {
    const user = new User(email);
    userRepository.add(user);
  }
}

这有效,并从持久性层中清除了所有溢出物.但我必须在要添加用户的每个地方都要做此操作.推荐的模式是什么?您还有其他鼓励的方法吗?您将在哪里进行检查以引发错误.

This works and removes any spillage from the persistance layer. but I'd have to do this every single place I'd want to add a user. What is the recommended pattern you would go for? Do you have another approach you'd encourage? Where would you do those checks to throw errors.

推荐答案

完全依靠数据库功能来实施业务规则是一种不好的做法.

Exclusively relying on database capabilities to enforce business rules is a bad practice.

也就是说,鉴于引发域异常是经过一些业务验证检查的事实,因此您不应该从代表数据库(存储库)的类内部引发域异常.

That said, given the fact that raising a domain exception follows some business validation check, you should not raise domain exceptions from inside the class representing your database (the repository).

域名例外,顾名思义,应在域(或应用程序)层内部使用.

Domain exceptions, as the name implies, should be used inside the domain (or application) layer.

因此,您的重复电子邮件验证应放在用例内,然后是存储库操作(添加用户).至于代码重复,解决方案很简单:使用包含此两阶段逻辑(先验证再进行操作)的方法创建域服务,然后在您想要的任何地方使用该服务.

Your duplicate-email validation should therefore be positioned inside use case, followed by the repository operation (add-user). As for code repetition the solution is simple: create a domain service with a method containing this two-phase logic (validation then operation) and use this service anywhere you'd like.

干净架构的关键原理是形成稳定的域层,同时允许基础结构细节可交换.但是,当您将业务规则放入存储库(基础结构)中时,请考虑如果决定创建备用存储库会发生什么:您必须记住将业务规则复制到新存储库中.

A key principle of the clean architecture is to form a stabilized domain layer while letting infrastructural details be exchangeable. But, when you put a business rule inside a repository (infrastructure), consider what will happen if you decide to create an alternative repository: you have to remember to copy your business rule into the new repository.

这篇关于存储库应该引发域错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆