首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >领域驱动设计验证逻辑

领域驱动设计验证逻辑
EN

Software Engineering用户
提问于 2019-11-15 09:00:57
回答 2查看 1.4K关注 0票数 3

我试图实现DDD与六角形架构。我正在努力解决的问题之一是验证。我已经研究了很多关于验证应该在哪里的文章,但是似乎没有一种方法。我想在我的场景中找到最合适的实现方式。这是一个场景。

  • 我有一个HTML页面,其中包含几个字段,如标题,日期,收货人。
  • 此HTML页面对空字段具有基本的验证。提交表单后,它将调用rest服务之一。
  • Rest Controller的工作就是将从浏览器发送的数据发送到服务之一。
  • 因此,服务类中的方法将接受该输入。我不相信来电者。我想在创建任何域对象之前验证输入。
  • 这里是我需要执行的验证示例
    • 标题不应为空
    • 标题长度应小于X字符(X的值是可配置的,并从数据库中检索)
    • 分配应该来自一组预定义的可用赋值(从另一个应用程序或DB检索)。

实现的解决方案(目前)从一个接口开始。

代码语言:javascript
复制
  public interface IValidator<T> {
     public ValidationResult validate(T entity)
  }

然后,我实现了多个验证器。例如,TitleValidator、DateValidator和AssignmentValidator。

由于实现的数量可能会增加,我已经创建了一个包装器来保存和配置验证器。最后,将包装器注入到服务中。

代码语言:javascript
复制
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以检索这些配置。

这是正确的方式还是每个验证器都应该自己检索其配置?

任何建议,改进或指导,更有经验的开发人员将不胜感激。

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2019-11-15 11:19:50

你也许应该回顾一下解析,不要验证背后的想法..。

这是正确的方式,还是每个验证器都应该自己检索其配置?

实际上,我不认为这很重要。

您在这里描述的是试图确保这里的数据与其他地方的数据一致。坦白说你不能这么做。您可以做的是确保这里的数据与来自其他地方的本地数据副本一致。

这里至少有三种不同的逻辑思想--如何处理数据的本地副本,如何获得数据的本地副本,如果获取本地数据副本的过程失败/超时,您将做什么?

请注意,这三种思想中只有一种真正关心的是数据库与web。

您可能需要从同一数据的本地副本创建多个验证器--想想数据传输对象。根据真正的一致性要求,这可能意味着您在构建验证器时共享一个读取缓存,或者不共享。

我猜最重要的是要注意清洁模块边界。也就是说,当你在未来改变你的想法时,你会关心的是(a)这些变化是你的代码中的某个部分的本地的,(b)很容易就知道该代码在哪里。

哦,还有你的依赖关系的方向;参见Mark的talk 异步注入 --如果您能够将问题分解为组件而不了解上下文,那么您的生活就会容易得多,而这些组件是由了解上下文的组件使用的。

您是否建议我们应该将配置数据(DTO)注入到验证器构造函数中,而不是建议验证器检索配置数据以进行验证?

我的意思是,如果你把问题分解成逻辑上可分离的部分,那么其中一个部分就会知道如何使用内存中的数据进行验证,而没有其他的了。

代码语言:javascript
复制
// 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无效的情况--使用此签名,您将不得不抛出一个异常,但是可以将这种不确定性编码到方法签名中

代码语言:javascript
复制
Optional<ValidatedInput> validatedDataFrom( /* ... */ ) {}
Either<ValidatedInput, List<ValidationErrors>> validatedDataFrom( /* ... */ ) {}

为什么我们需要返回ValidatedInput

我们“不需要”这样做,但我们可能不希望我们的使用者代码与我们的验证代码(它们是不同的想法,因为不同的原因而改变),并且使用类型系统消除了某种类型的错误(将未经验证的数据传递给假设验证数据的函数)。

这是ValueObject模式在第一本域驱动设计书中的另一个应用程序。我们在代码中明确了验证数据和未验证数据不是一回事(尽管底层表示可能类似),并利用类型系统确保在必要时满足更强的保证。

票数 3
EN

Software Engineering用户

发布于 2023-01-01 19:50:57

IMHO,这些验证似乎与DB有关。无论如何,它们不仅适用于当前的应用程序,而且也适用于您的域,因为不应该存在具有无效数据的实体( domain =域的所有可能的应用程序)。因此,我会将它们包括在域实体中。也确实,有些人在域层中包括域服务和模型。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/401117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档