我目前正在尝试消化与DDD中的不变量和验证相关的信息。如果我得到了正确的验证不是一个领域的关注,应该做外部,以防止不变量的发生。另一方面,不变量必须在域中强制执行,特别是在Aggregates中。
让我困惑的是两件事:
让我详细说明一下。考虑到我们有一个涵盖投标书的领域模型。投标过程组织者( (Participant). )和投标过程参与方( actors )是两个主要的参与者。组织者发布招标公告,其中包含关于阶段条款和要求的信息(例如,开始最高价格)。Tender是一个由多个阶段组成的过程。每个舞台都有自己的条件。第一个阶段的是“招标”。在这个阶段,允许参与者发送他的报价(Proposal)。
有两项基本要求:
从技术上讲,我们可以这样实现它(省略细节):
class SubmitHandler
{
/**
* Send proposal
*
* @param SubmitCommand $command
*/
public function execute($command)
{
$this->isReadyToBeSend($command);
$participant = $this->participantRepository->find($command->id);
$participant->submitProposal();
}
private function isReadyToBeSend($command)
{
$result = $this->validate($command);
if (!$result->isValid()) {
throw new ProposalException($result->getMessages()[0]->getMessage());
}
}
public function validate($command)
{
// Here we check if starting price is provided
// and it is less than starting maximum price
// as well as the Call for bids Stage is still active
// so that we are allowed to submit proposals
return Validator::validateForSending($command);
}
public function canBeExecuted($command)
{
return $this->validate($command)->isValid();
}
}
// In the UI we send command to the handler
$commandHandler->handle($submitCommand);
class Participant extends AggregateRoot
{
public function submitProposal()
{
// here we must enforce the invariants
// but the code seems to be almost the same as
// in the validator in the Command Handler
$this->isReadyToBeSent();
}
// throws exceptions if invariants are broken
private function isReadyToBeSent()
{
$this->isPriceCorrect();
$this->AreTermsCorrect();
}
}考虑到上面提到的一切,在给定的上下文中,不变量和验证之间有什么细微的区别?应该在验证器和聚合中复制代码吗?(我不想将验证器注入实体)
非常感谢。
更新
我想我还不够清楚。长话短说,我有两件事要考虑:
我和另一位开发人员最近进行了一次讨论,我们得出的结论如下:
如果我错了,请纠正我。
发布于 2014-03-28 23:58:44
尽管我已经编写了很多DDD代码,但坦率地说,我仍然对术语不太确定,我也不确定是否有社区的共识。我已经很大程度上不再使用DDD的行话了,我发现我的问题比你提出的问题少得多。
所以另一种用实际术语表述问题的方法是..。
被出价较低的人超过将真正激怒你的用户,就像在一个关闭的拍卖中的出价一样。所以我们得确保那不会发生。
读取数据时的验证
当您显示供用户输入出价的屏幕时,您当然会对用户进行一些验证,即出价必须大于以前的出价(例如通过jQuery),并且只有在CallForBids阶段才能接受投标(例如,只显示表单)。
你必须做这个验证,否则你会给用户一个非常糟糕的体验-允许他们进入一个出价,但被告知拍卖结束。因此,我们知道,在读取数据时,您必须以某种方式表达这些规则。然而,关键是:
您不能保证根据A时的信息在屏幕上显示的任何内容在用户执行在B时写入数据的操作时都是正确的。
所以这里的验证不一定是密封的。别担心太多了。即使你重复逻辑而搞砸了,我们也不能100%地保证一次写无论如何都会通过。
写入数据时的验证
正如我们上面观察到的,屏幕上的数据已经过时:用户可能在拍卖结束后输入了出价,或者由于数据显示在屏幕上,最低出价可能已经上升。因此,为了避免系统的状态违反业务规则(因此是不可靠的,没有完整性).
在编写数据时,您必须根据业务规则进行检查,并且必须在同一个事务中进行检查,否则无法保证一致性。
(也有最终的一致性,但这是另一个蜡球,超出了这个答案的范围。)
那对你来说意味着什么?
希望这能把它弄清楚。
https://stackoverflow.com/questions/22525780
复制相似问题