私はPHPでプロジェクトを行っており、アグリゲートとイベントソーシングを実装しています。ESに関連するすべてのロジックを自分でコーディングしないようにするために、サードパーティのライブラリを使用することにしました EventSauce と呼ばれます。
私のコード、特に私のドメインを外部ライブラリと結合しないようにしたいと思います。ただし、ドキュメントで見たことから、EventSauceインターフェースを実装するクラスを使用する必要があります。ライブラリに加えられる可能性のある変更を制御するために、または将来的に別のライブラリに変更したい場合は、自分のインターフェースを使用したいと思います。これを例で説明します。
次のインターフェイスを持つリポジトリがあります。
interface ItemRepository
{
public function itemOfSku(Sku $sku): Item;
public function nextSku(): Sku;
public function save(Item $item): void;
}
また、ライブラリには、次のような同等のインターフェイスが必要です。
interface MessageRepository
{
public function persist(Message ... $messages);
public function retrieveAll(AggregateRootId $id): Generator;
}
ライブラリの他の部分はこのMessageRepository
に依存しているため、このインターフェイスを実装する必要があります。この制限が存在しない場合は、はるかに簡単です。
ドメインを汚染せずにサードパーティのインターフェースからデコルプできるようにするデザインパターンがあるかどうか知りたいのですが。
あなたが直面している根本的な問題は、ドメインオブジェクトのメソッド/フィールドを呼び出すときにメッセージオブジェクトを生成する必要があることです。
イベントソーシングを実行する場合、これについてできることは多くありません。単純なItemRepositoryを保持している場合、Save(Item)
を呼び出すと、基になるイベントソースデータベースは、リポジトリからアイテムを取得して戻すまでの間に発生した事柄のリストを解決する方法がありません。再び。あらゆる種類のイベントソーシングを実装するために必要なこと。
もちろん、ライブラリのMessageオブジェクトを使用する必要はありません。独自のイベントを使用してから、ItemRepository.Saveを呼び出すときにそのイベントのリストをメッセージに変換できます。
class ItemRepository
{
private MessageRepository messageRepo;
public function save(Item $item): void
{
foreach(var i in item.Events)
{
messageRepo.Persist(ConvertToMessage(i));
}
}
}
これは重要な情報を見逃す可能性があるため、beforeオブジェクトとafterオブジェクトを比較してイベントを推測しないように注意してください。