1

プレゼンテーション層がどのように構成されているかが、集約ルートを設計するためのリードになるかどうか疑問に思っていました。

エンティティ ProjectEntity とその関連エンティティ ProjectMemberEntity (1:M) を作成します。

このページは次のように構成されています。

ページ上部は ProjectEntity のフォームです

フォームの下には、ProjectMemberEntity のリストを表示するグリッドがあります。

新しい ProjectMember が追加される場合、ユーザーはこのページに移動し、グリッドのヘッダーにある [新しいメンバーの追加] ボタンをクリックする必要があります。編集と削除も同じように類似しています。

この動作/「ページ構造」が集約ルート(projectentity)のヒントになるかどうか疑問に思っています

4

2 に答える 2

1

それは確かにヒントです。しかし、もうありません。

そのエンティティ関係の種類を明確にするより良い方法は、ドメインの専門家に尋ねることです。

  • プロジェクトメンバーはプロジェクトなしで意味がありますか?
  • メンバーは複数のプロジェクトに参加できますか?

それらが肯定的に回答された場合、プロジェクト メンバーを集約ルート自体としてモデル化する必要がある可能性が高くなります。それ以外の場合 - プロジェクトなしでは生きられないエンティティとして降格します。


ここにいくつかのアイデアを与えるかもしれないいくつかのコードがあります:

public class Project:Root{
 private List _members;
 public IEnumerable<Member> Members{get {return _members;}}
 public string Name{get;private set;}
 public bool IsFinished{get;private set;}
 public bool FinishedOn{get;private set;}
 public Project(string projectName){
  _members=new List<Member>();
  Name=projectName;
 }
 public Member AssignMember(string memberName){
  var member=new Member(memberName);
  _members.Add(member);
  return member;
 }
 public void UnassignMember(string memberName){
  var member=_members.First(m=>m.Name==memberName);
  if(!member.HasCompletedAllTasks())
   throw new Exception
    ("Cannot unassign member with incompleted tasks!");
  _members.Remove(member);
 }
 public void AssignTaskToMember(string taskName, string memberName){
  var member=_members.First(m=>m.Name==memberName);
  member.AssignTask(taskName);
 }
 public void MemberHasCompletedTask(Member member, Task task){
  EnsureListContains(_members,member);
  EnsureListContains(member.Tasks,task);
  task.MarkAsCompleted();
 }    
 public void FinishProject(){
  if(_members.Any(m=>!m.HasCompletedAllTasks()))
   throw new Exception
    ("Can't finish project before members have completed all their tasks.");
  IsFinished=true;
  FinishedOn=DateTime.Now;
 }
 private void EnsureListContains<T>(IList<T> lst, T itm){
  if(!lst.Contains(itm)) throw new Exception();
 }
}

public class Member:Entity{
 public string Name{get;private set;}
 private List<Task> _tasks;
 public IEnumerable<Task> Tasks{get{return _tasks;}}
 internal Member(string memberName){
  Name=name;
  _tasks=new List<Task>();
 }
 internal void AssignTask(string taskName){
  _tasks.Add(new Task(taskName));
 }
 public bool HasCompletedAllTasks(){
  return _tasks.All(t=>t.IsCompleted);
 }
 public Task GetNextAssignedTask(){
  return _tasks.Where(t=>!t.IsCompleted)
    .OrderBy(t=>t.AssignedOn).First();
 }
}

public class Task:Entity{
 public string Name{get; private set;}
 public bool IsCompleted{get; private set;}
 public DateTime CompletedOn{get; private set;}    
 public DateTime AssignedOn{get; private set;}
 internal Task(string name){
  Name=name;
  AssignedOn=DateTime.Now;
 }
 internal void MarkAsCompleted(){
  if(IsCompleted) throw new Exception
   ("Task is already completed!");
  IsCompleted=true;
  CompletedOn=DateTime.Now;
 }
}

public class App{
 public static void Main(){
  var project=new Project
    ("Question: Aggregate root design and presentation layer");
  var me=project.AssignMember("Arnis Lapsa");
  project.AssignTaskToMember("Try to help user137348","Lapsa");
  var currentTask=me.GetNextAssignedTask();
  //SpamStackOverflow();
  project.MemberHasCompletedTask(me,currentTask);
  if(me.HasCompletedAllTasks()) project.Finish();
  else throw new Exception("Enough for today...");
 }
}

あなたのビジネスが何であるかについて、私はほとんど知識がありませんでした。これはただの即興です。:)

于 2011-01-06T13:58:44.597 に答える
0

DDD に関して言えば、ドメインと集計を設計しようとするときに分析麻痺に陥らないように注意してください。それは私に起こりました。私のプロジェクトは、集計をまっすぐにすることができなかったため、文字通り丸 1 か月停止しました。そして、単純な 3 つのデータベース テーブルの状況について話しています。ユーザー、アドレス、およびユーザー プロファイル。

DDD の問題は、DONE THE RIGHT WAY のようなものがないということです。ここに同じ質問を 3 か月間隔で投稿すると、常に「専門家」から質問ごとにまったく異なる回答が得られます。Amis L. は親切にも、確かでシンプルな例を提供してくれました。ほとんどの人は、エリックの本からコピーして貼り付けます。

あなたのボートを浮かせることは何でもしてください。結局のところ、あなたのドメインがどれほど手作りであっても、それがコミュニティにとって正しいとは限りません。リラックスしてコーディングをお楽しみください。

于 2012-12-17T00:09:18.003 に答える