2

序章

3 つのドメイン オブジェクトがあるとします。

Proposition
Phase
Task

提案は、1 つ以上のフェーズを持つことができます。フェーズには、1 つ以上のタスクを含めることができます。

最後のフェーズの最後のタスクを完了した場合、提案は「クローズ」に設定する必要があります。

コードでは、フェーズの最後のタスクを完了するためにこのようなものを作成しました

//My Business Layer does this:
--------------------------------------
pseudo:
var phase = _phaseRepository.GetById(id);
phase.LastTask.SetComplete();


// My Domain Entities look like this:
------------------------
public class phase()
{
   public Task LastTask { get; set; } // not real code of course
}

public class Task()
{
   public Phase Phase { get; set; }

   public void SetComplete()
   {
      Phase.IsFinished = true;
   }
}

質問

提案を「クローズ」に設定するコードはどこに配置すればよいですか?

オプション

いくつかのオプションがあると思います:

1) ドメイン エンティティ内: Task.SetComplete

public class Task()
{
   public Phase Phase { get; set; }

   public void SetComplete()
   {
      Phase.IsFinished = true;
      Phase.Proposition.IsClosed = true;
   }
}

2a) ビジネス層で

var phase = _phaseRepository.GetById(id);
phase.LastTask.SetComplete();

var proposition = _propositionRepository.GetById(phase.PropositionId);
proposition.IsClosed = true;

2b) ビジネス層では、おそらくもう少し良い方法です:

var phase = _phaseRepository.GetByIdIncludingProposition(id);
phase.LastTask.SetComplete();
phase.proposition.SetClosed();

3) すべてを命題に通す:

//My Business Layer:
var proposition = _propositionRepository.GetById(id);
proposition.CompleteTask(taskId);

// Domain Object:
public class Proposition()
{
   public List<Phase> Phases { get; set; }

   public void CompleteTask(long taskId)
   {
      var task = // psuedo: select relevant task from Phases.Tasks, using taskid
      task.SetComplete();
      task.Phase.SetFinished();

      //psuedo: if task.Phase is last phase in proposition
      Phase.Proposition.IsClosed = true;
   }
}

オプションについて

オプション 1は回線上で問題があります

Phase.Proposition.IsClosed = true;

命題はロードする必要がなく、ロードされていない場合は例外が発生するためです。

オプション 2aには問題があります。これは、phase.LastTask.SetComplete() が実行された後、命題が正しい状態にないためです。そして、フェーズにアクセスできるコード内のどこでも、"phase.LastTask.SetComplete()" は命題に関連する操作を実行せずに実行できます。

オプション 2bには 2a と同じ問題があります。

オプション 3では、命題クラスに過度の責任が与えられます。

何か提案はありますか?

4

1 に答える 1

1

命題は集約ルートであると推測しています.タスクは最終的に命題の一部であり、Tsskは完了したことを通知する必要があると思います.このアプローチを試してみます(基本的にオプション3を少し変更しました).

public class Proposition()
{
  public Task GetTask(int taskId)
  {
      //find and return task
  } 
}

//in business layer 
var p= _repository.GetProposition(id);
p.GetTask(taskId).SetComplete();

public class Task
{
  public event Action<Task> Completed;       


   public void SetComplete()
   {
        if (Completed!=null) Completed(this);
    }

フェーズはタスクの完了イベントを処理し、それがトリガーされると、それが最後のタスクであるかどうかを確認し、それ自体を閉じるようにプロポシトンに通知する必要があります。おそらく、イベントを使用することは最良の実装ではありません。おそらく、オブザーバー パターンの方が優れていますが、主なアイデアは次のとおりです。

  • Propositionメソッドを介してタスクを取得します(PropositionはARであるため)
  • タスクは、完了時にフェーズに通知します
  • フェーズは、最後のタスクが完了すると提案を通知します
  • 提案は、進行中のフェーズがないかどうかを確認し、それ自体を閉じる必要があります。
  • 命題をリポジトリに保存する

考えてみれば、これは基本的にドメイン イベント パターンです。

于 2012-02-15T10:48:28.160 に答える