2010-10-11 15 views
18

Tengo una aplicación MVC2 n-tier (DAL, Dominio, Servicio, MVC web) usando un enfoque DDD (Diseño Dirigido por Dominio), teniendo un Modelo de Dominio con repositorios. Mi capa de servicio usa un patrón Solicitud/Respuesta, en el que los objetos Solicitud y Respuesta contienen DTO (Objetos de transferencia de datos) para ordenar los datos de una capa a la siguiente, y la asignación se realiza a través de la ayuda de AutoMapper. Mi pregunta es la siguiente: ¿qué forma debería tomar una DTO? ¿Puede tener anidado/complejo DTO también o debería ser estrictamente una proyección plana? ¿O posiblemente una mezcla de ambos? Además, ¿cuáles son las principales razones para tener un DTO plano frente a un DTO más complejo/anidado?Forma DTO: plana, compleja/anidada, o una mezcla de ambos

Por ejemplo, supongamos que tenía un dominio como el siguiente:

public class Employee 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Company Company { get; set; } 
} 
public class Company 
{ 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
} 

Hay tres maneras diferentes que he pensado de modelar el objeto Response.

Opción 1 - la opción DRYest:

public class GetEmployeeResponse 
{ 
    public class EmployeeDTO { get; set; } // contains a CompanyDTO property 
} 

De la investigación que he hecho, no sería apropiado para un DTO para tomar una forma similar a la del objeto de dominio (s) como se ha demostrado anteriormente .

Opción 2 - una proyección aplanada del dominio (anti-DRY):

public class GetEmployeeResponse 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string CompanyName { get; set; } 
    public string CompanyAddress { get; set; } 
    public string CompanyCity { get; set; } 
    public string CompanyState { get; set; } 
} 

Esto es más simple, como un DTO aparentemente debería ser, pero en última instancia hace que para más DTO.

Opción 3 - una mezcla de ambos:

public class GetEmployeeResponse 
{ 
    public EmployeeDTO Employee { get; set; } 
    public CompanyDTO Company { get; set; } 
} 

Esto permite que el código sea un poco más seco, reutilizable y manejable, y no expone la estructura de mi dominio para el usuario final . El otro beneficio principal es que otras respuestas, como GetCompanyResponse podrían simplemente devolver CompanyDTO, sin tener que hacer una copia de todas esas propiedades, similar a la opción 2. ¿Qué opina usted? ¿Qué opción de estos (si corresponde) ha tomado y/o ha trabajado para usted? Si estas Solicitudes/Respuestas se exponen posteriormente como métodos de servicio de WCF, ¿cambia su respuesta?

+1

¿Por qué se construye la aplicación MVC n-tier en primer lugar? No estoy diciendo que esté mal. Siendo curioso qué ventaja obtienes al poner servicios entre tu modelo de dominio y el nivel web –

+1

Solo quiero responder a un comentario específico que hiciste: "haz una copia de todas esas propiedades". Una vez que su sistema alcanza un cierto umbral de complejidad, puede ser mejor tener un modelo de lectura dedicado que esté desnormalizado en el nivel de la base de datos (ya sea por vistas o en su configuración de ORM). Cuando comencé a hacer esto, me permitió construir modelos de dominio mucho más complejos porque no tenía que preocuparme por el gasto de hidratarlos para el lado de las consultas.Quiero decir, ¿por qué hidratar varios modelos si vas a desnormalizarlos? Deje que el DB haga eso. Es lo que es bueno de todos modos. – Ryan

+0

@Szymon Hay MUCHAS ventajas de tener un nivel de servicio. Para mí, la mayor ventaja es que puedo poner toda la seguridad en una capa y no dejar que se filtre en mis controladores. – Ryan

Respuesta

11

Mi preferencia personal sería tratar de mantenerlo plano como sea posible con solo transferir los datos requeridos. una vez dicho esto, he utilizado DTO profundamente anidado en el pasado porque tenía sentido en ese momento y se ajustaba a los requisitos. así que supongo que todo se reduce a "depende". Al final del día, vaya con lo que tenga sentido para la aplicación en cuestión. No tiene sentido tratar de meter los datos de cuerno en una convención de DTO que no se ajusta a lo que está tratando de lograr.

+0

Aka: no tire el sentido común por la ventana solo para lograr un patrón de diseño ambiguo y vago (DTO). ;) ¿Cómo se almacena la información jerárquica (categorías de productos) en un DTO plano? – jfar

+0

@jfar Uno de los factores que miro, es la conversación de la aplicación. Si hay mucho tráfico sobre el cable (es decir, el cliente solicita muchos pequeños datos) solo para mostrar la página de información, buscaría consolidarlo en una solicitud de información y devolver los datos en un formato adecuado. . –

+0

@jfar Si le conviniera, probablemente denormalizaría, por lo que incluyó la categoría como parte del producto. Como dije en mi respuesta, prefiero mantenerlo lo más plano posible, pero eso no significa que deba ser plano como un panqueque. Si tener un DTO jerárquico hace que sea más fácil escribir y mantener el código en el idioma de su elección, entonces elegiría esa ruta como lo hice en el pasado cuando uso servicios web con MS InfoPath. Intentar aplanar el DTO no tenía sentido en ese caso. las necesidades de datos de la aplicación definen el DTO. –