Guía de estructura de proyecto de aplicación en capas MVVM, DDD y WPF

17

Estoy tratando de configurar la estructura de mi aplicación en VS y quiero "probar" y probarlo en el futuro a un nivel razonable. Esta aplicación será una reescritura de WPF de una vieja aplicación Winform que no había seguido ninguna convención. Sin capas, niveles, siglas, etc.

Es una aplicación empresarial bastante grande. Planeaba usar Linq To SQL como mis bases de datos son y probablemente siempre serán MS SQL. También tengo un conjunto de habilidades existente con él.

Quiero seguir MVVM y DDD lo mejor que pueda, pero me confundo en la estructura de mi aplicación al combinarlos. Déjame intentar e ilustrar con algunos ejemplos.

Cuando sigo MVVM, la estructura de mi carpeta puede verse así:

Views
Models
ViewModels
Helpers

pero ¿cómo encaja eso en un enfoque simplificado en capas DDD donde mi estructura de proyecto podría parecerse a esto:

MyApp.UI
MyApp.Domain
MyApp.Data

¿Pongo el Modelsen la capa de dominio o tengo 3 versiones de say Person? Esto lleva a otra pregunta de dónde colocaría mi repositorio y las asignaciones del objeto DB al objeto de dominio. Supongo que Data ...

ViewsMe gustaría ir en la interfaz de usuario pero ViewModelstambién?

Finalmente, ¿dónde estaría incrustando mi Business Logic?

Encontré lo siguiente en CodePlex, DDD Example , y ha sido de alguna ayuda, pero parece ser para una aplicación web, aunque eso puede no importar y mi ignorancia está brillando.

No me malinterpretes, sé que puedo tener tantas carpetas y llamarlas como quiera. Estoy tratando de averiguar dónde colocar las cosas para que esto sea escalable, no cómo se llaman necesariamente esos lugares.

El corazón de mi pregunta podría mostrarse así.
Tengo un tblPersonobjeto generado por *.dbml. Esto es obvio y pertenecería a mi capa "Datos".
Ahora tendría Modelo, DTO, Modelo de dominio, o como se llame en una Capa separada (¿proyecto?) Llamada Person. Yo necesitaría una Mapperpara Persona tblPersonque no estoy seguro de dónde poner.
Entonces, tendré un ViewModel para, por ejemplo, EditPersonque tendría sus propias propiedades de las que extrae, Personpero posiblemente también más.
Finalmente tendría una vista que estaba vinculada a ese modelo de vista ...

Para que quede claro que el párrafo está LLENO con mis suposiciones y conjeturas, y espero que alguien me ayude a aclarar el aire u ofrecer ideas para que de 6 meses a un año a partir de ahora no me patee más de lo necesario.

Paladín Refractado
fuente
Linq To SQL no es adecuado para proyectos más grandes. Utilice Entity Framework u ORM diferente como nHibernate. Además, ¿es esta aplicación solo para clientes o cliente-servidor?
Eufórico
Es una aplicación solo para clientes de WPF. Además, ¿podría explicar por qué siente que L2S no es apto para una aplicación de tamaño mediano o grande cuando mi única fuente de datos es MS SQL?
Paladín refractado el

Respuestas:

5

MVVM es un patrón de UI y se usa en un cliente.

Las partes del dominio en DDD que se usan en el cliente son probablemente (una parte de) el Modelo

View y ViewModel son solo para clientes.

Puse Repositorios en (o cerca) del Modelo porque sincronizan el Modelo con el back-end.

Sí, muchas veces esto resultará en múltiples clases de Persona en diferentes espacios de nombres. Pueden comenzar de manera muy similar, pero pueden terminar muy diferentes después de un par de iteraciones o lanzamientos.

EDITAR

Para aclarar la parte sobre repositorios y explicar más sobre el posicionamiento de Business Logic

Si está creando un sistema que contiene un cliente separado y los repositorios del lado del servidor / back-end se pueden usar en el cliente y el servidor. En el cliente para proporcionar una abstracción de los servidores y en el servidor para proporcionar una abstracción de otros servidores y fuentes de datos. Es solo un patrón.

En cuanto a las reglas comerciales: si las usa en el cliente, asegúrese de aplicarlas también en el servidor. Nunca confíes en un cliente. Las reglas comerciales en el cliente permiten una validación de entrada rápida y evitan los viajes de ida y vuelta al servidor.

Creo que DDD pertenece en el lado del servidor y 'filtra' al cliente.

Erno
fuente
2

Tiene la dirección correcta al elegir el patrón de diseño MVVM para la aplicación WPF.

Do I put the Models in the Domain layer?

Sí, tus modelos se pueden colocar en el dominio

Where would I put my Repository and mappings of DB Object to Domain Object?

Sus repositorios se pueden colocar en la capa donde se ubica su dominio. Sus objetos de mapeo (también llamados DTO - objetos de transferencia de dominio) deben colocarse en su capa de servicio y puede usar una poderosa herramienta de mapeo AutoMapper para mapear fácilmente sus objetos de dominio a DTO.

ViewModels also?

Sus ViewModels deben colocarse en el lado del cliente (capa). Puede construir sus modelos de vista a partir de uno o más DTO, según sus puntos de vista.

Con respecto a DDD , sugeriría leer sobre esto y aclararle que realmente necesita tener un patrón de diseño controlado por dominio. Aquí hay una discusión de que el 95% de todas las aplicaciones de software caen en las categorías "no tan bueno para usar DDD".

Editar: la referencia se ha agregado anteriormente, y gracias por @Den!

Yusubov
fuente
por favor, comente cuando rechace la votación.
Yusubov
1
Los fanáticos de DDD quieren usarlo en todas partes. Enlace relacionado: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den
@ Den, gracias por el enlace! Estaba planeando buscarlo.
Yusubov
1

Antes de profundizar en lo que va a dónde, hablemos sobre lo que debería estar haciendo cada capa.

El punto de venta de MVVM es la unión entre la vista y el modelo de vista. El objetivo aquí es eliminar la lógica dentro de la vista.
Al igual que la Vista, el Modelo debe ser bastante liviano y usarse solo para acceder a la información (datos) necesaria para que funcione el modelo de vista. El modelo puede combinar el acceso a diferentes fuentes de datos, pero no debe tener lógica empresarial. En la mayoría de los casos, tiene un único almacén de datos para golpear. En algunos casos no lo haces. Cuando no lo hace, es apropiado usar el Modelo para ocultar el origen de los datos de la VM.

Un punto implícito de MVVM es que los datos ya están almacenados y su proyecto no es responsable de mantener su organización. Algunos proyectos tienen la suerte de salirse con la suposición, la mayoría de los proyectos en los que he trabajado no han tenido tanta suerte. Baste decir que los datos son otra capa con la que tendremos que lidiar.

Expondría mi proyecto así:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

y esta capa se puede agregar según sea necesario:

 project.Helpers

Estoy separando los Helpers del resto de la pila para que no se confunda como una capa de su pila de aplicaciones.

Descargo de responsabilidad: no soy un experto en DDD, pero entiendo la esencia general y veo el valor en el enfoque.

Su dominio será el conjunto de problemas que está considerando.
Los modelos de dominio se corresponderán principalmente con los modelos de vista que cree; un poco dentro de las Vistas; y un pequeño fragmento dentro de Model / DataStructs.

Entonces, ¿cómo va a funcionar eso?
SI tiene la capacidad de cambiar las estructuras de datos existentes, entonces las nuevas que cree deben correlacionarse con el problema que está tratando de resolver. ¿Tienes un objeto de cliente? Entonces debe tener algunas tablas relacionadas con el Cliente. ¿Tienes facturas o productos? Misma historia: se deben crear tablas y estructuras que se asignen a esos objetos comerciales.

El dominio se expresará a través de sus objetos ViewModel y las vistas que presente de esos objetos. Si necesita editar registros de clientes, tendrá una máquina virtual para manejar esa tarea.

A sus preguntas:

  1. No intentes superponer DDD en MVVM. Simplemente no va a funcionar. DDD no es un patrón de diseño, es un enfoque para ver su problema general.
  2. El repositorio y las asignaciones vivirán en proyecto, datos o proyecto, según corresponda.
  3. No tenga una capa llamada IU a menos que sea lo que quiere llamar proyecto.
  4. Business Logic irá en la vista Modelo.

fuente
1
Bien, algunas, probablemente ignorantes, preguntas de seguimiento. (1) ¿haría de cada uno de ellos un proyecto separado o simplemente carpetas (por ejemplo, Project.View, etc.) (2) DataStructs es donde pondría los * .dbml o Project.Data? (3) Entonces, en su opinión, no tendría un Project.Domain? He visto que usado algunas veces es por eso que pregunto.
Paladín refractado el
@RefractedPaladin - 1) solo carpetas dentro del proyecto. Podría argumentar que los datos deberían ser su propio proyecto. Desde el punto de vista del mantenimiento, cualquier forma es equivalente. 2) sí, exactamente. 3) no, no tendría una carpeta .Domain. En mi opinión, nuestro trabajo es asignar la aplicación al dominio del problema comercial. Entonces el Dominio impregna todas las capas del proyecto.