我的域中有一个预算实体,如果预算开放,用户可以关闭该实体。这意味着,如果预算今天开始并在 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
}
...
}
我不知道如何解释它,但这似乎是业务逻辑,尽管这种情况(不在期间)似乎永远不会到达域,因为我将进行验证对于到达控制器的数据(但请记住,我还不知道所有业务规则和要求)。
这个时间限制引起了一个疑问:我是否应该在我的域代码中添加一个验证,如下所示,还是应该在将访问将访问域的服务的控制器中进行验证?
您大多数时候希望的是所有业务策略都在域模型中表达,而不是分散在整个代码中。
领域模型之外的东西不负责业务策略,但负责向领域模型提供信息。
所以你的例子可能看起来像这样:
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 是否正确处理其所有边缘情况确实很容易,因为在测试中您可以通过任何您想要的日期。