Nel precedente post abbiamo discusso il problema dell'"inquinamento" del Domain Model dovuto a proprietà utili solo all'interfaccia utente. Abbiamo concluso il post accennando al concetto di DTO.
Cos'è un DTO?
Un DTO in questo caso è un oggetto anemico (solo proprietà no metodi) che ha come unico scopo trasportare informazioni dall'application layer all'interfaccia utente (ed eventualmente viceversa).
Nell'esempio del post precedente la soluzione al problema del binding si risolve usando un DTO nel modo seguente:
public class EmployeeDTO : Employee
{
public String FullAddress
{
get { return String.Format("{0}, {1}", Address.Street, Address.City);}
}
}
L'oggetto EmployeeDTO sfrutta l'ereditarietà per avere tutte le proprietà dell'oggetto Employee con in più la proprietà FullAddress.
La soluzione proposta sopra benché immediata non è ancora la migliore. Il problema è che l'oggetto EmployeeDTO eredita da Employee e quindi ottiene tutte le proprietà e i metodi pubblici (e protetti) diventando cosi troppo ricco per chi lo utilizza facendo perdere la percezione del fatto che EmployeeDTO è solo un contenitore di dati (tra l'altro avrebbe a disposizione tutti i metodi del domain model!)
Oltre a questo problema, ne esiste un secondo. Supponiamo di voler esporre la proprietà Name dell'oggetto Employee sull'interfaccia facendo in modo che la prima lettera sia sempre maiuscola (solo a scopo di presentazione). Nella classe EmployeeDTO dovrei fare l'override della proprietà ma non essendo definita virtual nella classe base non lo posso fare. Quindi? Torna il problema dell'inquinamento del DM, questa volta marcando come virtual la proprietà Name.
Una soluzione migliore sta in uno dei principi base della programmazione ad oggetti: "Favor encapsulation over inheritance".
Nota: Papo nel post precedente, tramite un commento, diceva che non gli piaceva la T di DTO perché il concetto di Trasporto fa pensare ad un oggetto remoto cosa non sempre vera. Lui propone di usare il concetto di Vista invece che di DTO: cioè creare degli oggetti che fungono da vista sugli oggetti del domain model. L'implementazione non cambia è (solo) una questione di nomenclatura (e qui dovremmo aprire un altro discorso).
[Continua…]