php-EventSourcing、Aggregates –不変条件を2倍にすることなく操作する
私はアプリケーションでイベントソーシング手法をかなり基本的なレベルで試していますが、概念的な問題が発生しました。例に直接移りましょう。
ProductAggregateRoot.php
public function changePrice(ChangeProductPrice $command): self
{
if ($this->availability->equals(Availability::UNAVAILABLE())) {
throw CannotChangePriceException::unavailableProduct();
}
if ($this->price->equals($command->newPrice)) {
throw CannotChangePriceException::priceHasntChanged();
}
$this->recordThat(
new ProductPriceChanged($this->price, $command->newPrice)
);
return $this;
}
今、私は他の方法を作成したいと思います(またはドメインサービスでさえ、実際には重要ではありません)。
- 外部ソースから現在の価格と可用性を取得します
- 合計で価格を更新してみてください。
- 総計で可用性を更新してみてください。
ご覧のとおり、価格の更新中に、製品が利用できない場合は価格を変更できない、値が変更されていない場合は価格を変更できないなど、いくつかのビジネス不変条件を確認しています。不変条件のいずれかが壊れている場合は、例外をスローします。
今、私のドメインサービスにいるとき、外部データソースに基づいて価格と可用性を変更したいと思います。今、私は単に次のようなキャッチブロックを試してみました:
try {
$aggregate->changePrice(new ChangeProductPrice(
$productId,
$state->getPrice()
));
} catch (CannotChangePriceException $ex) {
}
価格用の1つのtry-catchブロック、可用性用の別のブロックなど。それは動作しますが、私はそれが単に間違っていてハッキーだと感じています。CanChangePrice()
ようなブロックとメソッド/仕様の場合、単純な方がはるかに快適です。しかし、私はそれを二重に使用する必要があります–サービスと具体的な方法自体の両方で、それも良く聞こえません。
問題は、皆さんはそのようなことをどのように処理するのかということです。それは非常に些細な問題のように思えますが、それでも私はそれについて気分が良くなるような解決策を見つけていません。
答え :
解決:
いくつかの考え:
「価格と在庫状況の変更」コマンドを使用してみませんか?これにより、両方を更新する意図がより適切にキャプチャされ、不変チェックでより適切なコンテキスト知識を得ることができます(たとえば、可用性を利用可能に更新する場合、現在の可用性は以前の遺物であるため意味がありません)。
価格を実際の現在の価格に変更しようとする試みをエラーと見なすのは少し疑わしいです。私の考えでは、このコマンドは、価格が希望の価格になるという願望を表現しているので、その願望がすでに満たされている場合、なぜそれを誤りにするのでしょうか。
$this
返す(事実上肩をすくめて「確かに」と言う)方が良いようで、リクエスターに現在の価格を強制することはありません(厳密に言えば、すでに知ることはできません)。
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。