progettazione radice aggregati e livello di presentazione
-
26-09-2019 - |
Domanda
Mi chiedevo se come il mio livello di presentazione è strutturata potrebbe essere un vantaggio per progettare le mie radici di aggregazione.
Consente di avere un'entità ProjectEntity e il relativo ProjectMemberEntity entità (1: M)
La pagina è strutturata come segue:
La parte superiore della pagina è un modulo per ProjectEntity
Sotto forma è una griglia che mostra un elenco di ProjectMemberEntity.
Se una nuova ProjectMember verrà aggiunto, l'utente deve andare a questa pagina e cliccare sul pulsante "aggiungi nuovo membro" che si trova nell'intestazione della modifica grid.also e cancellare ha la stessa analogia.
Mi chiedo se questo comportamento / 'la struttura della pagina' potrebbe essere un suggerimento per una radice di aggregazione (projectentity)
Soluzione
Questo è un suggerimento di sicuro. Ma non di più.
Modo migliore per chiarire tipo di rapporto che entità è di chiedere esperto di dominio:
- fa membro del progetto ha un senso, senza progetto?
- membro può partecipare a più progetti?
Se quelli sono risposto positivamente, è altamente probabile che si dovrebbe modellare membro del progetto come una radice di aggregazione per sé. In caso contrario -. Abbassare come un'entità che non può vivere w / o un progetto
Ecco alcuni codice che potrebbe darvi qualche idea:
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...");
}
}
Tieni presente che ho avuto poca conoscenza di ciò che il commercio è circa. Questa è solo un'improvvisazione. :)
Altri suggerimenti
Quando si tratta di DDD, assicurarsi che non si ottiene paralisi dell'analisi quando si cerca di progettare il vostro dominio e aggregati. È successo a me. Il mio progetto ha ottenuto letteralmente fermato per un mese intero perché non ero permetterà di ottenere i miei aggregati dritto. E sto parlando di una situazione tabelle del database semplice 3. Utente, indirizzo e UserProfile.
La cosa con DDD è che non esiste una cosa come un FATTO IL DIRITTO MODO. Se pubblichi la stessa domanda qui con un intervallo di 3 mesi l'una dall'altra, otterrete sempre gli "esperti" dando risposte completamente diverse in ogni domanda. Amis L. è stato così gentile da dare un esempio semplice solido. La maggior parte delle persone sarebbe copiare e incollare dai libri di Eric.
Do qualunque sia la vostra barca galleggia. Alla fine della giornata, non importa quanto artigianale il dominio è, non è mai DESTRA per la comunità. Basta rilassarsi e godere di codifica.