DDDとPropertyChanged/CollactionChangedイベントの組み合わせが最適なアイデアかもしれないと私は心配しています。問題は、これらのイベントの周りにあなたのロジックを置くと、PropertyChangedが別のものや別のものにつながり、すぐにあなたが緩やかなコントロールになるので、複雑さを管理することは非常に難しいことです。
ProportyChangedイベントとDDDが正確に適合しないもう1つの理由は、DDDではすべてのビジネス操作ができるだけ明示的でなければならないということです。 DDDはビジネスの世界に技術的なものをもたらしてくれることを覚えておいてください。そして、PropertyChanged/CollectionChangedを基にすることはあまり明白ではありません。
はDDDでは主な目標は、あなたが(操作はもちろん、成功した場合)あなたは集計が有効かつ一貫性のある呼び出しどんな操作するような方法で集計し、モデル化する必要がある他の言葉で、集約内の一貫性を維持することです。
「ビルド」トランザクションを心配する必要がないようにモデルを構築すれば、集合体の操作はトランザクション自体でなければなりません。
モデルがどのように見えるかはわかりませんが、PropertyChangedイベントに頼るのではなく、プロセス内で論理エンティティを追加する可能性があります。
例:
はあなたがステータスといつでも支払いの変更は、あなたが顧客の注文のトータルバランスを再計算したいと支払いのコレクションを持っていると仮定します。代わりに支払いコレクションへの変更をサブスクライブして、コレクションの変更は、あなたがこのような何かを行う可能性がある場合、お客様のメソッドを呼び出す:
public class CustomerOrder
{
public List<Payment> Payments { get; }
public Balance BalanceForOrder { get; }
public void SetPaymentAsReceived(Guid paymentId)
{
Payments.First(p => p.PaymentId == paymentId).Status = PaymentStatus.Received;
RecalculateBalance();
}
}
あなたは、私たちは、単一の順序のバランスやないのバランスを再計算することを、気づいたかもしれません顧客全体が他の集約に属しており、必要に応じてその残高を簡単に照会できるため、ほとんどの場合、大丈夫です。これは正確に、この「集約内の一貫性」を示す部分です。現時点では他の集約は気にしません。単一の注文のみを処理します。それが要件を満たしていない場合、ドメインは正しくモデル化されていません。
私の指摘は、DDDではすべてのシナリオに対して単一の良いモデルがないことです。ビジネスの成功の仕組みを理解する必要があります。
上記の例を見ると、トランザクションを「ビルド」する必要がないことがわかります。トランザクション全体はSetPaymentAsReceived
メソッドにあります。ほとんどの場合、ユーザーアクションの1つは、集約を持つエンティティの1つの特定のメソッドにつながるはずです。このメソッドはビジネスオペレーションに明示的に関連しています(もちろんこのメソッドは他のメソッドを呼び出すことがあります)。
DDDのイベントに関しては、Domain Eventsという概念がありますが、これはPropertyChanged/CollectionChangedの技術イベントとは直接関係しません。ドメインイベントは、集計によって完了したビジネスオペレーション(トランザクション)を示します。
Overalドメインモデル内のすべてのロジックをプッシュすると、それは複雑なビジネスロジックとのシナリオで使用されるようになっているとして行いもちろん
かなり複雑 ドメインモデルを作るようです。しかし、ドメインが正しくモデル化されていれば、この複雑さを管理し制御することは容易であり、それがDDDの利点の1つです。例を提供した後に追加されました
:
[OK]を、どのようなプロジェクトと呼ばれる集約ルートの作成について - あなたはリポジトリからの集約ルートを構築するとき、あなたはNetworkDataでそれを埋めることができ、操作が次のようになります。
public class Project
{
protected List<Network> networks;
protected List<NetworkData> networkDatas;
public void Mutate(string someKindOfNetworkId, object someParam)
{
var network = networks.First(n => n.Id == someKindOfNetworkId);
var someResult = network.DoSomething(someParam);
networkDatas.Where(d => d.NetworkId == someKindOfNetworkId)
.ToList()
.ForEach(d => d.DoSomething(someResult, someParam));
}
}
NetworkEditorは、NetworkIdを使用するプロジェクトではなく、ネットワーク上で直接動作しません。
Spot on。 DDDエンティティは正当にプロパティとコレクションの変更を報告できますが、プレゼンテーションコードのような外部のオブザーバに対してのみ、ドメインロジックの目的には使用できません。 – jnm2