Estoy intentando dar el salto desde el diseño y desarrollo centrado en datos a DDD y he leído a Evans y Nillson, pero sigo teniendo problemas para entender cómo debería estructurar mi capa de dominio . ¡Estoy seguro de que la naturaleza de mi proyecto actual no está ayudando!DDD real: estructurar la capa de dominio
Un poco de historia
La aplicación es una solución interna para gestionar las evaluaciones de personal. El personal de recursos humanos creará "plantillas" de evaluación que consisten en un conjunto de preguntas que el equipo lidera y los gerentes deben completar para cada uno de sus informes directos. Las respuestas se mantienen para la auditoría y revisión. Estas evaluaciones pueden ser para una amplia variedad de cosas tales como retroalimentación para las iniciativas de la compañía, evaluaciones de desempeño, etc.
La parte centrada en los datos de mi
no influir en la solución, pero destacando mi centrada en los datos mentalidad, ya tengo una visión para el esquema de base de datos y lo incluyo aquí sólo para referencia (ya que una imagen vale más que mil palabras):
el esquema es, como era de esperar, normalizado y no lo hace emparejar cómo los datos se manejan en mi aplicación. Y, he omitido las tablas de búsqueda y similares para tratar de mantenerlo al mínimo para el problema en cuestión.
Los casos de uso
El primer caso de uso es para recuperar y mostrar una lista de evaluaciones que un usuario necesita para completar. Esto se mostrará cuando el usuario ingrese por primera vez a la aplicación y, al principio, parece que sería relativamente fácil, pero hay dos inconvenientes: 1 - las evaluaciones se basan en el tiempo, por lo que pueden ser requeridas mensualmente, anualmente o cada 'x' número de años basado en la Fecha de Aniversario del empleado; y, 2: los usuarios pueden guardar una evaluación en curso y completarla más tarde. Como resultado, la lista debe contener las evaluaciones pendientes y las que están en progreso.
A continuación, cuando el usuario selecciona una evaluación para realizar, necesito recuperar todas las preguntas para esa evaluación (la versión actual) para que pueda mostrarlas al usuario. En cualquier punto durante la evaluación, el usuario puede guardar los resultados actuales. Solo después de que se haya completado toda la evaluación, en realidad puede ser 'enviada' o confirmada.
En tercer lugar, Recursos Humanos necesita una forma de volver a generar la evaluación con las respuestas proporcionadas por el supervisor.
Finalmente, HR puede crear y modificar evaluaciones, y están versionadas. Por lo tanto, cada vez que alguien modifica una evaluación, se crea una nueva versión y esa se convierte en la plantilla para las NUEVAS evaluaciones que se realizan (las evaluaciones en progreso continúan usando su plantilla original).
Modelo El dominio
Trabajar fuera de orden, tiene sentido para mí que voy a tener una entidad de evaluación que es una raíz agregado para satisfacer el cuarto caso de uso. Tendrá una colección secundaria de entidades de sección que, a su vez, tendrá una colección secundaria de entidades de pregunta. Son todas las entidades porque tienen identidad (¿sí?). La evaluación es el objeto que el código consumidor usa para persistencia, validación, etc. (aunque las entidades de Sección y Pregunta se validan a sí mismas y acumulan el estado a la Evaluación raíz).Mi objetivo es hacer el resumen de versiones del consumidor e implementarlo en la capa de persistencia de datos (¿buena o mala idea?)
Esto significa que también tendré un RecoveryRepository que maneja la persistencia para mí y, posiblemente, una AssessmentFactory eso crea una nueva evaluación cuando sea necesario.
El problema mayor viene con los otros casos de uso. ¿Tengo una raíz agregado de evaluación de empleados también? ¿O es simplemente una entidad?
En cuanto a los casos de uso, necesito utilizar esta información de varias maneras. Primero, cuando estoy generando la lista de evaluaciones para mostrar al usuario, no solo debo evaluar la lista de informes directos en comparación con la frecuencia de evaluación, sino que también necesito saber si ya comencé y/o realicé una evaluación. para ese empleado. Y eso proviene de la tabla EmployeeAssessments. El otro caso es cuando un usuario realmente lleva a cabo la evaluación, en cuyo caso estoy interactuando con las tablas EmployeeAssessments and Responses.
Desde la perspectiva de la interfaz de usuario, cuando un usuario realiza la evaluación, no conocen nada de la estructura de datos interna, etc. Necesito proporcionar a la UI la lista de preguntas para que se muestre y acepte la lista de respuestas persistir. ¿Esto lleva a una segunda raíz con el repositorio que lo acompaña, etc.?
El tercer caso de uso es similar en el sentido de que el departamento de recursos humanos desea poder volver a generar la evaluación con las respuestas en una fecha posterior. Sin embargo, estoy pensando que el mismo proceso utilizado al realizar la evaluación se puede usar aquí porque la reanudación de una evaluación existente requeriría la misma información, con la única diferencia de que es la capacidad de lectura/escritura versus la de solo lectura para la HR.
¡Termine ya!
De acuerdo, he hablado lo suficiente y creo que he despejado mi cabeza de las redes de mazorca. Aprecio cualquier dirección, sugerencia, crítica, etc. Como dije, estoy tratando de dar el salto y creo que entiendo los conceptos, ahora es cuestión de aplicarlos. ¡¡¡Gracias!!!
Bien, estoy contigo. Centrémonos en el primer caso de uso donde necesito generar la lista de evaluaciones pendientes o en progreso para el usuario actual. Estoy luchando con qué parte de la lógica para resolver si se incluye una evaluación debería estar en la capa de dominio frente a lo que podría hacerse fácilmente en SQL. ¿Realmente quiero que el objeto de dominio Evaluación contenga una lista de objetos AssessmentVersion y que mi clase Specification cree una Expression que use "evaluation.Versions" para que toda la lógica esté en el código? – SonOfPirate
Además, pienso que tendré un AssessmentService que expone un método ListMyDueAssessments() que crea una instancia de la clase MyDueAssessmentSpecification y la pasa al método AssessmentRepository.Find (spec). Find() devuelve una lista de objetos de evaluación que satisfacen la expresión proporcionada por la clase de especificación. ¿Estoy en el camino correcto? ¿Qué pasa con la devolución de una clase AssessmentInfo que es una versión más liviana y aplanada, esto es consistente con DDD? – SonOfPirate