Domain driven design 聚合根设计和表示层

Domain driven design 聚合根设计和表示层,domain-driven-design,aggregateroot,Domain Driven Design,Aggregateroot,我想知道我的表示层的结构是否可以作为设计聚合根的线索 让我们有一个实体ProjectEntity及其相关实体ProjectMemberEntity(1:M) 该页面的结构如下所示: 页面顶部是ProjectEntity的表单 表单下面是一个网格,显示ProjectMemberEntity的列表 如果要添加新的ProjectMember,用户必须转到该页面并单击位于网格标题中的“添加新成员”按钮。编辑和删除也具有相同的相似性 我想知道这种行为/“页面结构”是否可能是对聚合根(projectenti

我想知道我的表示层的结构是否可以作为设计聚合根的线索

让我们有一个实体ProjectEntity及其相关实体ProjectMemberEntity(1:M)

该页面的结构如下所示:

页面顶部是ProjectEntity的表单

表单下面是一个网格,显示ProjectMemberEntity的列表

如果要添加新的ProjectMember,用户必须转到该页面并单击位于网格标题中的“添加新成员”按钮。编辑和删除也具有相同的相似性


我想知道这种行为/“页面结构”是否可能是对聚合根(projectentity)的提示,这是一个肯定的提示。但是没有了

澄清这种实体关系的更好方法是询问领域专家:

  • 没有项目,项目成员有意义吗
  • 成员能否参与多个项目
如果答案是肯定的,那么很可能您应该将项目成员建模为聚合根。否则-将其降级为无法在没有项目的情况下生存的实体


下面是一些代码,可能会给您一些想法:

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...");
 }
}
公共类项目:Root{
私人名单(u成员),;
公共IEnumerable成员{get{return\u Members;}}
公共字符串名称{get;private set;}
公共bool已完成{get;private set;}
公共bool FinishedOn{get;private set;}
公共项目(字符串projectName){
_成员=新列表();
名称=项目名称;
}
公共成员AssignMember(字符串memberName){
var成员=新成员(成员名称);
_成员。添加(成员);
返回成员;
}
public void UnassignMember(字符串memberName){
var member=\u members.First(m=>m.Name==memberName);
如果(!member.HasCompletedAllTasks())
抛出新异常
(“无法取消分配任务未完成的成员!”);
_成员。移除(成员);
}
public void AssignTaskToMember(字符串taskName、字符串memberName){
var member=\u members.First(m=>m.Name==memberName);
成员。分配任务(任务名称);
}
public void MemberHasCompletedTask(成员成员,任务任务){
EnsureRelistContains(_成员,成员);
EnsureRelistContains(成员.任务,任务);
task.MarkAsCompleted();
}    
公共空间完成项目(){
如果(_members.Any(m=>!m.HasCompletedAllTasks()))
抛出新异常
(“在成员完成所有任务之前无法完成项目。”);
IsFinished=true;
FinishedOn=DateTime.Now;
}
私有无效的EnsureListContains(IList lst、T itm){
如果(!lst.Contains(itm))抛出新异常();
}
}
公共类成员:实体{
公共字符串名称{get;private set;}
私有列表任务;
公共IEnumerable任务{get{return\u Tasks;}}
内部成员(字符串成员名){
名称=名称;
_任务=新列表();
}
内部无效分配任务(字符串taskName){
_任务。添加(新任务(任务名称));
}
public bool已完成所有任务(){
返回_tasks.All(t=>t.IsCompleted);
}
公共任务GetNextAsignedTask(){
返回_tasks.Where(t=>!t.IsCompleted)
.OrderBy(t=>t.AssignedOn).First();
}
}
公共类任务:实体{
公共字符串名称{get;private set;}
公共bool已完成{get;private set;}
在{get;private set;}上完成公共日期时间
在{get;private set;}上分配的公共日期时间
内部任务(字符串名称){
名称=名称;
AssignedOn=DateTime.Now;
}
内部无效标记已完成(){
如果(IsCompleted)抛出新异常
(“任务已完成!”);
IsCompleted=真;
CompletedOn=DateTime.Now;
}
}
公共类应用程序{
公共静态void Main(){
var项目=新项目
(“问题:聚合根设计和表示层”);
var me=项目转让成员(“Arnis Lapsa”);
project.AssignTaskToMember(“尝试帮助用户137348”,“Lapsa”);
var currentTask=me.getNextAsignedTask();
//垃圾邮件溢出();
project.MemberHasCompletedTask(me,currentTask);
如果(me.HasCompletedAllTasks())project.Finish();
否则抛出新异常(“今天就足够了…”);
}
}

请记住,我对你们的业务了解甚少。这只是一个即兴创作。:)

这肯定是一个暗示。但是没有了

澄清这种实体关系的更好方法是询问领域专家:

  • 没有项目,项目成员有意义吗
  • 成员能否参与多个项目
如果答案是肯定的,那么很可能您应该将项目成员建模为聚合根。否则-将其降级为无法在没有项目的情况下生存的实体


下面是一些代码,可能会给您一些想法:

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...");
 }
}
公共类项目:Root{
私人名单(u成员),;
公共IEnumerable成员{get{return\u Members;}}
公共字符串名称{get;private set;}
公共bool已完成{get;private set;}
公共bool FinishedOn{get;private set;}
公共项目(字符串projectName){
_成员=新列表();
名称=项目名称;
}
公共成员AssignMember(字符串memberName){
var成员=新成员(成员名称);
_成员。添加(成员);
返回成员;
}
public void UnassignMember(字符串memberName){
var member=\u members.First(m=>m.Name==memberName);
如果(!member.HasCompletedAllTasks())
抛出新异常
(“无法取消分配任务未完成的成员!”);
_成员。移除(成员);
}
public void AssignTaskToMember(字符串taskName、字符串memberName){
var member=\u members.First(m=>m.Name==memberName);
成员。分配任务(任务名称);
}
public void MemberHasCompletedTask(成员成员,任务任务){
EnsureRelistContains(_成员,成员);
EnsureRelistContains(成员.任务,任务);
task.MarkAsCompleted();
}    
公共空间完成项目(){
如果(_members.Any(m=>!m.HasCompletedAllTasks()))
抛出新异常
(“在成员完成所有任务之前无法完成项目。”);
IsFinished=true;
FinishedOn=DateTime.Now;
}
私有无效的EnsureListContains(IList lst、T itm){
如果(!lst.Contains(itm))抛出新异常();
}
}
公共信用