2011-08-10 7 views
1

私はドメインモデルを使用しようとしているアプリケーションで作業しています。アイデアは、ビジネスロジックをドメインモデル内のオブジェクトの中に保持することです。現在は、関連するオブジェクトに加入しているオブジェクトによって多くの変更が反映されます。これはPropertyChangedとCollectionChangedによって行われます。この作業は次の点を除いてOKです。ドメインモデルはイベントを使用して一貫性を維持する必要がありますか?

複雑なアクション:多くの変更をグループとして処理する必要があります(個々のプロパティ/コレクションの変更は処理しません)。どうすれば私はトランザクションを構築できますか?

永続性:私は持続性のためにNHibernateを使用しています。これはクラスのパブリックプロパティセッターも使用します。 NHibernateがプロパティにヒットすると、多くのビジネスロジックが実行されます(これは不要です)。私はNHibernateのカスタムセッターを使用する必要がありますか?

ドメインモデル内のすべてのロジックをプッシュすると、ドメインモデルがかなり複雑になります。何か案は???ここで

は(私が使用安っぽいツーリングのため申し訳ありません)「サンプル」問題です:

enter image description here

あなたはそれ以下のプロジェクト私のコンテナとオブジェクトがサブスクライブすることによって、相互に反応している見ることができます。ネットワークへの変更はNetworkEditor経由で行われますが、このエディタはNetworkDataに関する知識がありません。このデータは、別のアセンブリで定義されることさえあります。このフローは、ユーザ→ネットワークエディタ→ネットワーク→ネットワークデータと、他のすべてのオブジェクトから得られます。これは一定の縮尺ではないようです。

答えて

2

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を使用するプロジェクトではなく、ネットワーク上で直接動作しません。

+0

Spot on。 DDDエンティティは正当にプロパティとコレクションの変更を報告できますが、プレゼンテーションコードのような外部のオブザーバに対してのみ、ドメインロジックの目的には使用できません。 – jnm2

関連する問題