【发布时间】:2014-08-08 07:52:31
【问题描述】:
假设我们有一个 BankCard 实体,它是 Client Aggregate 的一部分。 客户可能想取消她的银行卡
class CancellBankCardCommandHandler
{
public function Execute(CancelBankCardCommand $command)
{
$client = $this->_repository->get($command->clienId);
$bankCard = $client->getBankCard($command->bankCardId);
$bankCard->clientCancelsBankCard();
$this->_repository->add($client);
}
}
class BankCard implements Entity
{
// constructor and some other methods ...
public function clientCancelsBankCard()
{
$this->apply(new BankCardWasCancelled($this->id);
}
}
class Client implements AggregateRoot
{
protected $_bankCards;
public function getBankCard($bankCardId)
{
if (!array_key_exists($bankCardId, $this->_bankCards) {
throw new DomainException('Bank card is not found!');
}
return $this->_bankCard[$bankCardId]);
}
}
最后我们有一些域存储库实例负责存储聚合。
class ClientRepository implements DomainRepository
{
// methods omitted
public function add($clientAggregate)
{
// here we somehow need to store BankCardWasCancelled event
// which is a part of BankCard Entity
}
}
我的问题是 AggregateRoot 是否负责跟踪其实体的事件。是否可以从聚合中获取作为聚合一部分的实体的事件?
如何真正持久化客户对银行卡所做的所有更改以保存其一致性?
【问题讨论】:
-
我猜想,就像您不直接在子实体上公开公共属性和方法一样,您也不应该公开事件。我希望您的聚合根可以订阅您的子实体事件,但如果它想公开这些事件,那么它会通过从聚合根引发新事件来实现。
-
“如果它想公开这些事件,那么它将通过从聚合根中引发新事件来实现”。我是否正确理解在我的情况下我必须在客户端上实现一个更改银行卡的方法?客户->cancellBankCard($cardId);如果是这样的话,问题是可能不是BankCard,而是一个非常庞大的Entity,它有很多业务逻辑,但它不能是另一个AggregateRoot,因为它的一致性边界完全取决于Client。
-
关于聚合大小的主题,听起来好像客户和银行卡应该以某种方式联系起来,而不是它是客户聚合的一部分。
标签: domain-driven-design cqrs event-sourcing