2017-05-24 14 views
0

私はこの単純なドメインモデルを持っています。ユーザーは、長さと距離を持つアクティビティを実行します。各アクティビティには、使用される歯車アイテム(ランニングシューズ)を割り当てることができます。割り当て後、ギアアイテムの合計に期間と距離が加算されます。1つのトランザクション(DDD)で2つの集計を変更する

アクティビティとGearItemの両方が集約ルートです。アイテムをアクティビティに割り当てるとき、アイテムのIDをアクティビティに追加し、アイテムの合計を更新する必要があります。

この操作を調整するにはどうすればよいですか?

  1. GearItem.AssignUsage()Activity.AddItem()から直接電話しますか?
  2. Activity.AddItem()の直後にGearItem.AssignUsage()を呼び出して、1つのトランザクションでアプリケーションサービスを実行します(ARごとに1つのトランザクションのルールが破られます)。
  3. ドメインイベント(Udi Dahanの静的クラス)を使用しますが、単一のトランザクションの問題をどのように回避するか?
  4. 他にも、はるかに優れていますか?割り当てGearItemsのIDが含まれ、

    public class GearItem: Entity<GearItem> 
    { 
        ... 
    public Usage AssignedUsage { get; private set; }; 
    
        public void AssignUsage(Activity activity) 
        { 
        AssignedUsage = new Usage(AssignedUsage.Time + activity.Time, 
        AssignedUsage.Distance + activity.Distance, AssignedUsage.Uses + 1); 
        }  
    } 
    

    活性AR:

    public class Activity: Entity<Activity> 
    { 
        ... 
        private List<int> items = new List<int>(); 
        public TimeSpan Time { get; } 
        public double Distance { get; } 
    
        public bool AddItem(GearItem item) 
        { 
        if (items.Contains(item.Id)) return false; 
    
        items.Add(item.Id); 
        return true; 
        } 
    } 
    

    使用値オブジェクト:

GearItem ARは、アクティビティの合計を含んでいます

public class Usage: ValueObject<Usage> { ... public TimeSpan Time { get; private set; } public double Distance { get; private set; } public int Uses { get; private set; } } 

答えて

2

1回のトランザクションで2つの集計を変更する誘惑に抵抗する必要があります。

  1. リファレンスその他の集計を唯一の彼らのIDで
  2. 使用結果整合性

だから、境界の外側のためAssignedUsageを更新するために、:あなたがそれをしないのに役立つ2つのルールがあります。 GearItemあなたは最終的な一貫性を使用します。

ドメインイベントを使用して、またはすべてGearItemsの使用状況を定期的に計算することで、これを行うことができます。

GearItemが活動に割り当てられた後、あなたが最初にそのIDを使用してGearItemをロードすることによって、新しいトランザクションでGearItem.AssignUsage(Time,Distance)を呼び出しProcess manager(によってキャッチされGearItemAssignedToActivityイベントを公開:ドメインのイベントを使用して

リポジトリから)。

は定期的に、あなたがすべてのActivityと負荷をロードし、割り当てられた各GearItemためGearItem.AssignUsage(Time,Distance)を呼び出し、その後、各GearItemに使用状況をリセットするものは何でもするcron /スケジュールされたタスク/でGearItemの使い方

を更新します。

また、2つの集計を切り離し、メソッド呼び出しの参照を渡さないことをお勧めします。たとえば、アクティビティ集約全体をGearItem.AssignUsageメソッドに渡すのではなく、必要なプロパティのみを渡すべきです。このようにしてGearItemは、Activity全体を知っていても、それに依存してはいけません。

関連する問題