Oop 如果不存储更改,存储库是否应该引发异常?
在规定我的存储库的合同期间,我开始怀疑任何Oop 如果不存储更改,存储库是否应该引发异常?,oop,exception,repository,domain-driven-design,design-by-contract,Oop,Exception,Repository,Domain Driven Design,Design By Contract,在规定我的存储库的合同期间,我开始怀疑任何存储库的基本合同是什么: 如果使用不存储更改的实体调用Update,会发生什么情况? 作为存储库的客户,如果我想存储更改,我只会调用更新。如果没有变化,我会假设我的流程中出现了一些错误,所以我想知道这个事实 所以我想说:未提交的更改是更新方法的先决条件。 如果不满足此前提条件,则需要抛出一个异常 但这里有另一种观点:存储库对更改漠不关心。Update方法只是确保给定实体保持现在的状态如果有任何更改,则不是存储库的业务。因此也不例外 就我个人而言,我倾向于
存储库的基本合同是什么:
如果使用不存储更改的实体调用Update
,会发生什么情况?
作为存储库
的客户,如果我想存储更改,我只会调用更新
。如果没有变化,我会假设我的流程中出现了一些错误,所以我想知道这个事实
所以我想说:未提交的更改是更新方法的先决条件。
如果不满足此前提条件,则需要抛出一个异常
但这里有另一种观点:存储库对更改漠不关心。Update
方法只是确保给定实体保持现在的状态如果有任何更改,则不是存储库的
业务。因此也不例外
就我个人而言,我倾向于看1,因为术语Update
本身表明发生了变化
你对这个话题有什么看法
PS:让我们假设(为了这个例子)不涉及并发,这当然会导致其他可能的结果。如果您完全确定未提交的更改是一个先决条件,那么如果该先决条件没有满足,您就有理由引发异常。
如果这是一个先决条件,那么在可能有更改或没有更改的情况下,您可以排除非异常调用update。如果这是你想要的,那好吧
然而,正如您在第2点中所暗示的,它并不是真正做了任何异常工作的存储库
您可以考虑在您真正期望更改的情况下,在更新之前是否有任何未提交的更改。
这与删除前文件不存在时是否应该抛出文件删除的问题非常相似。在某些用例中,我真的希望该文件存在,因此如果它不存在,那将是例外,然而另一个用例是我想确保该文件不存在,但我不知道(或关心)它当前是否存在。在这种情况下,如果我考虑POST条件“在删除调用之后不存在指定的文件”,那么(除非文件存在并且是不可删除的)文件是否已经存在。
update post条件是调用后没有未提交的更改,这对于成功更新和无需更新的情况都是符合的
在满足post条件的这些非异常情况下,必须捕获异常是令人恼火的。如果有一个选项或不同的方法可以区分前提条件应该适用或不应该适用的情况,那么代码的意图就会更清楚,这可能比单独检查先决条件更有效/更容易。如果您完全确定未提交的更改是先决条件,那么您有理由在未满足该先决条件时引发异常。
如果这是一个先决条件,那么在可能有更改或没有更改的情况下,您可以排除非异常调用update。如果这是你想要的,那好吧
然而,正如您在第2点中所暗示的,它并不是真正做了任何异常工作的存储库
您可以考虑在您真正期望更改的情况下,在更新之前是否有任何未提交的更改。
这与删除前文件不存在时是否应该抛出文件删除的问题非常相似。在某些用例中,我真的希望该文件存在,因此如果它不存在,那将是例外,然而另一个用例是我想确保该文件不存在,但我不知道(或关心)它当前是否存在。在这种情况下,如果我考虑POST条件“在删除调用之后不存在指定的文件”,那么(除非文件存在并且是不可删除的)文件是否已经存在。
update post条件是调用后没有未提交的更改,这对于成功更新和无需更新的情况都是符合的
在满足post条件的这些非异常情况下,必须捕获异常是令人恼火的。如果有一个选项或不同的方法可以区分前提条件应适用或不应适用的情况,那么代码的意图会更清楚,这可能比单独检查前提条件更有效/更容易
如果使用不存储更改的实体调用Update,会发生什么情况
我想你想让这成为一个禁区
使用持久性支持的存储库的常见模式
此代码位于应用程序组件中;存储库和货物聚合根是允许域模型了解的抽象。实施的细节在其他地方
里德尔:如果在当前状态下,cargo.assignToRoute
是一个no-op,会发生什么?应用程序无法知道这一点,因为它无法访问基础状态。它调用了模型,模型决定不更改任何内容,因此存储库会找到存储中可用的相同状态
这可能很重要,因为如果您的消息通过不可靠的传输(如web)发送给您,您可能会收到同一消息的两个副本。如果域模型认识到新的行程与旧的相同,则不需要更改任何内容
final Cargo cargo = cargoRepository.find(trackingId);
cargo.assignToRoute(itinerary);
cargoRepository.store(cargo);
final Cargo cargo = cargoRepository.find(trackingId);
cargo.assignToRoute(itinerary);
cargoRepository.store(cargo);
在这个流程中引入异常是否真的带来了业务价值?还是我们只是在为自己创造额外的工作
final Cargo cargo = cargoRepository.find(trackingId);
cargo.assignToRoute(itinerary);
cargoRepository.store(cargo);
final Cargo cargo = cargoRepository.find(trackingId);
cargo.assignToRoute(itinerary);
cargoRepository.store(cargo);
final Cargo cargo = cargoRepository.find(trackingId);
cargoRepository.store(cargo);