将业务逻辑放置在架构中作为数据验证

问题描述 投票:0回答:1

我的域中有一个预算实体,如果预算开放,用户可以关闭该实体。这意味着,如果预算今天开始并在 7 天内结束,在这段时间之间我可以关闭它,而不是之前(我必须删除它),而不是之后(无法执行任何操作)。

这个时间限制引起了一个疑问:我是否应该在我的域代码中添加一个验证,如下所示,还是应该在将访问将访问域的服务的控制器中进行验证?

class Budget {
  ...

  public close(): void {
    if (this.isOnPeriod()) {
      this.closed = true
    }
  }

  private isOnPeriod() {
    if (new Date() < this.closing_date) {
      throw new BudgetIsClosedError()
    }
    if (this.opening_date > new Date()) {
      throw new BudgetIsNotYetOpen()
    }

    return true
  }

  ...
}

我不知道如何解释它,但这似乎是业务逻辑,尽管这种情况(不在期间)似乎永远不会到达域,因为我将进行验证对于到达控制器的数据(但请记住,我还不知道所有业务规则和要求)。

validation domain-driven-design business-logic
1个回答
0
投票

这个时间限制引起了一个疑问:我是否应该在我的域代码中添加一个验证,如下所示,还是应该在将访问将访问域的服务的控制器中进行验证?

您大多数时候希望的是所有业务策略都在域模型中表达,而不是分散在整个代码中。

领域模型之外的东西不负责业务策略,但负责向领域模型提供信息。

所以你的例子可能看起来像这样:

  public close(Date today): void {
    if (this.isOnPeriod(today)) {
      this.closed = true
    }

在其他地方你会有类似这样的代码:

Date today = new Date();

Budget budget = someRepository.get(/* whatever */);
budget.close(today);

此设计的另一个优点:测试 Budget::close 是否正确处理其所有边缘情况确实很容易,因为在测试中您可以通过任何您想要的日期。

© www.soinside.com 2019 - 2024. All rights reserved.