ドメイン駆動設計とイベント ソーシングを試しています。それらをバインドするために、NServiceBus、JOliver の EventStore、および NES を使用 (C# で開発) する予定です。単純なケース (値オブジェクトのみを持つ 1 つの集約ルート) で機能するインフラストラクチャが既にあります。
私は Evans のブルーブックを読んでいて、私の仕事の分野 (HVAC メンテナンス会社の ERP と CRM) から例を挙げて、単純なドメイン モデルを開発しようとしています。
私は単純なサブドメイン、つまり HVAC マシンとそれらの間の関係をモデル化しています。機械には、炉、バーナー、エアコン、コンプレッサー、汎用コンポーネントなど、さまざまな種類があります。各マシンは、複数の子マシンを持つことができます。すべてのマシン タイプは、いくつかの共通のデータといくつかの共通の動作を共有します。ただし、各タイプには追加のデータと特定の動作があります。たとえば、Burner オブジェクトは Furnace にのみ追加できます。
私の分析の最初の結果は、特定のマシンへの参照を保持できる必要があるため (たとえば、単一のマシンを含む修理記録の挿入、障害の記録、など)、また、大規模なマシン ツリーでの同時実行の問題を軽減します。
したがって、私の仮説は次のとおりです。
public class Machine : AggregateBase
{
public DateTime InstallationDate { get; private set; }
public Guid ManufacturerId { get; private set; }
public Guid ModelId { get; private set; }
}
public class Furnace : Machine
{
public List<Burner> burners { get; private set; }
// other furnace properties
public void AddBurner(Burner burner)
{
// perform validation
this.Apply<BurnerAdded>(x=> x.burnerAdded = burner);
}
public void Handle(BurnerAdded @event)
{
this.burners.Add(@event.burnerAdded);
}
}
public class Burner : Machine
{
// burner specific properties/methods
}
しかし、私はいくつかの疑問があります:
これは私のドメインを表す正しい方法ですか? クラスの継承が推奨されていないことを読みましたが、これはそれを使用するのに最適なケースのようです (バーナーはマシンであり、ファーネスもそうです)。継承は 1 レベルに制限します。
イベントソーシングでクラス継承を実装することは可能ですか? 特に提案された技術スタック (nServiceBus、EventStore、NES) では?
子マシン (炉へのバーナーなど) の追加はどのように実行すればよいですか? この操作は次の 2 つに分けられます。
- 新しいバーナーをバーナー リポジトリに追加します。
- 親炉のバーナー リストにバーナーへの参照を追加しますが、これら 2 つの操作は 2 つの集約ルートをグローバルに変更するため、操作は 2 つの別個のコマンド ハンドラー/トランザクションで実行する必要があります... しかし、2 つ目は最初のものに依存します...これはモデリングエラーの証拠ですか?nServicebusMessages を一緒にバッチ処理して、単一のトランザクションでアクションを実行することもできますが、これは良くないことを読みました...
子マシンが親を参照するようにすると、親は (検証に必要な) 子マシンのリストを失い、Guid 以外のプロパティのイベント ソーシング リポジトリを照会できません。
ディスカッションへの貢献に感謝します。