我试图实现DDD与六角形架构。我正在努力解决的问题之一是验证。我已经研究了很多关于验证应该在哪里的文章,但是似乎没有一种方法。我想在我的场景中找到最合适的实现方式。这是一个场景。
实现的解决方案(目前)从一个接口开始。
public interface IValidator<T> {
public ValidationResult validate(T entity)
}然后,我实现了多个验证器。例如,TitleValidator、DateValidator和AssignmentValidator。
由于实现的数量可能会增加,我已经创建了一个包装器来保存和配置验证器。最后,将包装器注入到服务中。
public class MyService {
public MyService(WrapperValidator wrapperValidator){
}
public void createData(InputData inputData){
ValidationResult result = this.wrapperValidator.validate(inputData);
if(result.Ok()){
//Proceed with domain objects creation and applying business rules. Domain objects will have other validation as well.
}
}
}我检索配置参数,如最大长度、预定义的一组受让人,并将这些设置从包装器发送到验证器。
WrapperValidator正在访问数据库和外部API以检索这些配置。
任何建议,改进或指导,更有经验的开发人员将不胜感激。
发布于 2019-11-15 11:19:50
你也许应该回顾一下解析,不要验证背后的想法..。
这是正确的方式,还是每个验证器都应该自己检索其配置?
实际上,我不认为这很重要。
您在这里描述的是试图确保这里的数据与其他地方的数据一致。坦白说你不能这么做。您可以做的是确保这里的数据与来自其他地方的本地数据副本一致。
这里至少有三种不同的逻辑思想--如何处理数据的本地副本,如何获得数据的本地副本,如果获取本地数据副本的过程失败/超时,您将做什么?
请注意,这三种思想中只有一种真正关心的是数据库与web。
您可能需要从同一数据的本地副本创建多个验证器--想想数据传输对象。根据真正的一致性要求,这可能意味着您在构建验证器时共享一个读取缓存,或者不共享。
我猜最重要的是要注意清洁模块边界。也就是说,当你在未来改变你的想法时,你会关心的是(a)这些变化是你的代码中的某个部分的本地的,(b)很容易就知道该代码在哪里。
哦,还有你的依赖关系的方向;参见Mark的talk 异步注入 --如果您能够将问题分解为组件而不了解上下文,那么您的生活就会容易得多,而这些组件是由了解上下文的组件使用的。
您是否建议我们应该将配置数据(DTO)注入到验证器构造函数中,而不是建议验证器检索配置数据以进行验证?
我的意思是,如果你把问题分解成逻辑上可分离的部分,那么其中一个部分就会知道如何使用内存中的数据进行验证,而没有其他的了。
// This is a "pure function" or closure -- no side effects
// Notice that it doesn't care where its inputs come from.
ValidatedInput validatedDataFrom(
UnvalidatedInput fromUser,
Configuration currentConfiguration) {
// do something interesting with these two in memory representations
}当然,您也希望能够处理UnvalidatedInput无效的情况--使用此签名,您将不得不抛出一个异常,但是可以将这种不确定性编码到方法签名中
Optional<ValidatedInput> validatedDataFrom( /* ... */ ) {}
Either<ValidatedInput, List<ValidationErrors>> validatedDataFrom( /* ... */ ) {}为什么我们需要返回ValidatedInput
我们“不需要”这样做,但我们可能不希望我们的使用者代码与我们的验证代码(它们是不同的想法,因为不同的原因而改变),并且使用类型系统消除了某种类型的错误(将未经验证的数据传递给假设验证数据的函数)。
这是ValueObject模式在第一本域驱动设计书中的另一个应用程序。我们在代码中明确了验证数据和未验证数据不是一回事(尽管底层表示可能类似),并利用类型系统确保在必要时满足更强的保证。
发布于 2023-01-01 19:50:57
IMHO,这些验证似乎与DB有关。无论如何,它们不仅适用于当前的应用程序,而且也适用于您的域,因为不应该存在具有无效数据的实体( domain =域的所有可能的应用程序)。因此,我会将它们包括在域实体中。也确实,有些人在域层中包括域服务和模型。
https://softwareengineering.stackexchange.com/questions/401117
复制相似问题