An interesting thread si avvicinò quando ho digitato questa domanda proprio ora. Non penso che risponda alla mia domanda però.Un "modello di dominio ricco" può violare il Principio di Responsabilità Singola?
Ho lavorato molto con .NET MVC3, dove è preferibile avere un modello anemico. Visualizza modelli e modifica modelli sono i migliori come contenitori di dati stupidi che puoi passare da un controller a una vista. Qualsiasi tipo di flusso di applicazioni dovrebbe provenire dai controller e le visualizzazioni gestiscono i problemi dell'interfaccia utente. In MVC, non vogliamo alcun comportamento nel modello.
Tuttavia non vogliamo alcuna logica di business nei controller. Per le applicazioni più grandi è meglio tenere il codice del dominio separato e indipendente da modelli, viste e controllori (e HTTP in generale per quella materia). Quindi esiste un progetto separato che fornisce, prima di ogni altra cosa, un modello di dominio (con entità e oggetti valore, composti in aggregati secondo DDD).
Ho fatto qualche tentativo di allontanarmi da un modello anemico verso uno più ricco nel codice di dominio, e sto pensando di rinunciare. Mi sembra che avere classi di entità che contengono dati e comportamenti viola l'SRP.
Prendi ad esempio uno scenario molto comune sul web, componendo e-mail. Dato un certo evento, è responsabilità del dominio comporre un oggetto EmailMessage dato un EmailTemplate, EmailAddress e valori personalizzati. Il modello esiste come entità con proprietà e i valori personalizzati vengono forniti come input dall'utente. Diciamo anche per il ragionamento che l'indirizzo FROM di EmailMessage può essere fornito da un servizio esterno (IConfigurationManager.DefaultFromMailAddress). A fronte di tali requisiti, sembra un ricco modello di dominio potrebbe dare l'EmailTemplate la responsabilità di comporre l'EmailMessage:
public class EmailTemplate
{
public EmailMessage ComposeMessageTo(EmailAddress to,
IDictionary<string, string> customValues, IConfigurationManager config)
{
var emailMessage = new EmailMessage(); // internal constructor
// extension method
emailMessage.Body = this.BodyFormat.ApplyCustomValues(customValues);
emailMessage.From = this.From ?? config.DefaultFromMailAddress;
// bla bla bla
return emailMessage;
}
}
Questo è stato uno dei miei tentativi di ricco modello di dominio. Tuttavia, dopo aver aggiunto questo metodo, era responsabilità di EmailTemplate sia contenere le proprietà dei dati di entità che i messaggi di composizione. Era lungo circa 15 righe e sembrava distrarre la classe da ciò che significa realmente essere un EmailTemplate - che, IMO, è solo per memorizzare i dati (formato soggetto, formato del corpo, allegati e indirizzi opzionali da/reply-to).
Ho finito per refactoring questo metodo in una classe dedicata, che è l'unica responsabilità è la composizione di un EmailMessage dato gli argomenti precedenti, e io sono molto più felice con esso. In effetti, sto iniziando a preferire domini anemici perché mi aiuta a mantenere le responsabilità separate, rendendo le lezioni e i test unitari più brevi, più concisi e più mirati. Sembra che rendere entità e altri oggetti dati "privi di comportamento" possano essere utili per separare la responsabilità. O sono fuori pista qui?
Un modello di dominio ricco deve essere ricco appena sufficiente per il contesto in cui è rilevante. –