自動車工場の署名を変更して、完全なドライバーエンティティを受け入れることができます。その後、ファクトリーはそのエンティティーからIDを選択し、それを使用して車を構築します。ここでは、不変条件が暗黙的にチェックされます。
このアプローチは無料でチェックできるので魅力的です。また、ユビキタス言語とうまく連携しています。AはCar
によって駆動されていないdriverId
、しかしによりますDriver
。
このアプローチは、実際にそれにヴォーンバーノンで使用されているのですアイデンティティ&アクセス彼が通るサンプル有界コンテキストUser
に集約しGroup
、集約が、Group
唯一の値型に保持していますGroupMember
。ご覧のとおり、これにより彼はユーザーの有効性をチェックすることもできます(チェックが古くなっている可能性があることは十分に承知しています)。
public void addUser(User aUser) {
//original code omitted
this.assertArgumentTrue(aUser.isEnabled(), "User is not enabled.");
if (this.groupMembers().add(aUser.toGroupMember()) && !this.isInternalGroup()) {
//original code omitted
}
}
ただし、Driver
インスタンスを渡すことにより、Driver
内部での偶発的な変更に自分自身をさらすことにもなりますCar
。値の参照を渡すと、プログラマーの観点から変更を推論するのが簡単になりますが、同時にDDDはすべてユビキタス言語に関するものなので、おそらくリスクを冒す価値があります。
インターフェース分離原則(ISP)を適用するのに適切な名前を実際に思い付くことができる場合、動作メソッドを持たないインターフェースに依存する可能性があります。また、不変のドライバー参照を表し、既存のドライバー(例:)からのみインスタンス化できる値オブジェクトの概念を考え出すこともできますDriverDescriptor driver = driver.descriptor()
。
これらのアグリゲートが別の境界コンテキストに存在する可能性があることを想像できましたが、ドライバーBCのDriverRepositoryまたはDriverエンティティへの依存関係で車のBCを汚染します。
いいえ、実際にはそうしません。あるコンテキストの概念が別のコンテキストに流れ込まないようにするために、常に腐敗防止レイヤーがあります。あなたは車の運転手の団体専用のBCを持っている場合は、次のような既存の概念モデル化することができますので、それは実際にははるかに簡単だCar
とDriver
特にそのコンテキストのために。
したがって、DriverLookupService
BCで自動車と運転手の関連付けを管理する責任を定義している場合があります。このサービスは、ドライバーコンテキストによって公開されたWebサービスを呼び出す可能性があります。このサービスはDriver
、このコンテキストの値オブジェクトである可能性が最も高いインスタンスを返します。
Webサービスは必ずしもBC間の最良の統合方法であるとは限らないことに注意してください。また、たとえばUserCreated
、ドライバー管理コンテキストからのメッセージがリモートコンテキストで消費され、ドライバーの独自のDBにドライバーの表現を格納するメッセージングに依存することもできます。DriverLookupService
その後、このDBを使用することができ、ドライバのデータは、さらに、メッセージ(例えばで最新の状態に保たれることになりますDriverLicenceRevoked
)。
どちらのアプローチがドメインに適しているかははっきりとは言えませんが、決定を下すための十分な洞察が得られることを願っています。
Driver.delete
存在すべきではありません。アグリゲートが破壊されるドメインを見たことはありません。ARを維持することで、孤児になることはありません。