Proyecto compartido. En el taller de Intermodular que abre esta semana has trabajado comprobar el contrato publicado. En Servidor continúas la implementación del mismo producto.
Se explica
25 minutos · explicación y demostración
Ya dispones de capas, inyección y pruebas de reglas. Hoy revisarás que toda la API aplica esa separación antes de sustituir la memoria por PostgreSQL. La colección verifica el contrato HTTP y los tests del servicio verifican las decisiones internas: necesitas ambas comprobaciones.
Terminar es tachar
Una refactorización a medias es peor que no haberla empezado: deja dos formas de hacer lo mismo conviviendo, y quien llegue después no sabrá cuál es la buena.
Abre el análisis de problemas. Para cada línea, una de tres:
- Resuelto: táchalo y escribe en qué clase vive ahora eso
- Sigue vivo: resuélvelo hoy
- Ya no aplica: explica por qué dejó de ser un problema
No vale dejar líneas sin marcar. Ese documento es la justificación de la unidad y hoy es su comprobación.
Comprobar una refactorización completa
Refactorizar cambia cómo se organiza el código manteniendo el comportamiento acordado. Si la colección que pasaba antes deja de pasar, no basta con que las carpetas se llamen controller, service y repository: hay una regresión que localizar. La primera evidencia es la comparación del mismo recorrido antes y después.
El controlador interpreta HTTP y construye respuestas; el servicio ejecuta el caso de uso y sus reglas; el repositorio ofrece acceso a los datos. Para comprobar la separación, sigue una operación de escritura y pregunta quién decide si es válida, quién guarda y quién elige el estado HTTP. Una regla repetida en dos controladores debe tener un lugar común en el servicio.
Las pruebas de servicio completan la colección HTTP: permiten provocar un conflicto de negocio sin arrancar el servidor y comprobar que no se guarda un dato inválido. La revisión de hoy conecta ambas evidencias con el código. La arquitectura está terminada cuando es comprensible, comprobable y conserva el contrato; contar paquetes o anotaciones no demuestra esas propiedades.
Se trabaja
140 minutos · implementación guiada sobre el proyecto propio
Paso 1 · Retomar el proyecto y preparar la comprobación
- Abre el árbol de paquetes, los tests del servicio y la colección. Ejecuta ambos recorridos antes de corregir la arquitectura.
- Elige una regla y localiza su única implementación. Anota si se repite en otro controlador o depende indebidamente de HTTP.
- Selecciona otra entidad de tu dominio y comprueba qué capas o tests le faltan para alcanzar la misma estructura.
Paso 2 · Especificación · el estado final
Estructura del proyecto
com.ejemplo.gestor
├── controller · habla HTTP y nada más
├── dto · lo que se acepta y lo que se publica
├── mapper · traduce entre DTO y modelo
├── service · casos de uso y reglas de negocio
├── repository · interfaces, con su implementación en memoria
├── model · lo que maneja tu código
├── validacion · anotaciones propias
└── error · excepciones, formato y manejador
Reglas que se comprueban
| # | Criterio | Cómo se verifica |
|---|---|---|
| 1 | Ningún controlador tiene listas, bucles de búsqueda ni contadores | Búscalos |
| 2 | Ningún controlador contiene una regla de negocio | Léelos entero |
| 3 | Ningún service menciona HTTP, códigos, DTO ni ResponseEntity |
Busca Response en el paquete |
| 4 | Ningún repository conoce reglas de negocio | Léelos |
| 5 | No queda ningún new de un colaborador |
Busca new en controller y service |
| 6 | Todas las dependencias se piden por constructor y son final |
Léelas |
| 7 | Los repositorios son interfaces | Míralos |
| 8 | Cada clase lleva el estereotipo de su capa | Míralos |
| 9 | Cada caso de uso es un método público con nombre de negocio | Lee los nombres en voz alta |
| 10 | Cada regla de negocio tiene su test | Cuenta reglas y cuenta tests |
Estoy atascado · el controlador de la ruta anidada
GET /proyectos/{id}/tareas es el que suele quedarse a medias, porque toca dos recursos y es tentador resolverlo con dos llamadas desde el controlador.
Si tu controlador llama a dos servicios y decide algo entre medias, eso es coordinación, y la coordinación es del service. Decide en cuál vive el caso de uso y déjalo ahí entero.
Paso 3 · La doble comprobación
Ejecuta primero los tests del servicio con el backend detenido; su resultado debe depender de los objetos preparados por los tests. Después arranca el backend y ejecuta la colección HTTP con sus propios datos. Si falla un test, revisa regla y doble de prueba; si los tests pasan y falla HTTP, sigue la petición por controlador, mapper y servicio. Registra ambos resultados, porque comprueban límites distintos.
La colección
Demuestra que no has cambiado nada para quien consume la API. Es la prueba de que fue una refactorización.
Los tests
Demuestran que las reglas siguen siendo las que decidiste, y lo demostrarán otra vez dentro de seis meses.
Ambas deben superarse. Existe una tercera comprobación, la más exigente:
La prueba del cambio pequeño
Elige uno de estos y cronométralo de verdad:
- Que una tarea nueva nazca con prioridad
media. - Publicar un campo nuevo en la respuesta de proyectos.
- Añadir un filtro por prioridad al listado de tareas.
Apunta cuántos archivos has tenido que abrir y cuánto has tardado. Compáralo con la estimación que hiciste en el apartado 4 de el análisis de problemas, cuando todo estaba en el controlador. Esa diferencia es el resultado de la unidad.
Paso 4 · Preparar la evidencia de esta versión
- El proyecto con la estructura de la especificación.
- el análisis de problemas revisado, con cada línea tachada o justificada.
- Los tests, con al menos uno por regla de negocio, en verde con
./mvnw test. - La colección, en verde y sin ninguna petición modificada desde la UD3.
- las decisiones técnicas ampliado con tres:
- Dónde vive el caso de uso de la ruta anidada y por qué.
- Qué código de estado devuelve una regla de negocio incumplida en tu API, y por qué ese.
- Qué regla te costó más colocar y qué duda tuviste.
Paso 5 · Autoevaluación · pásale el código a otro
Intercambia el enlace a una versión concreta del repositorio. Clónala en otra carpeta, abre su README y prepara su configuración antes de ejecutar los comandos. Responde a las preguntas de la revisión señalando clase y método, no solo el nombre de una capa. Devuelve los pasos que faltaban en el README y una petición que reproduzca cada defecto encontrado; aplica después las correcciones equivalentes a tu proyecto.
- Intercambia el proyecto con un compañero.
- Sin preguntarle nada, y solo mirando los nombres de las clases y de los métodos, que responda por escrito:
- ¿Dónde se decide qué prioridad tiene una tarea nueva?
- ¿Dónde habría que tocar para cambiar de almacenamiento?
- ¿Dónde se decide qué código de estado devuelve un error?
- ¿Qué reglas de negocio tiene esta aplicación?
- Cada respuesta equivocada señala un nombre confuso o una responsabilidad mal colocada. Anótalas.
- Corrige tu proyecto con lo que salga de ahí.
La cuarta pregunta es la mejor: si tu compañero puede enumerar tus reglas de negocio leyendo los nombres de tus métodos y tus tests, la arquitectura está haciendo su trabajo.
Paso 6 · Lo que sigue faltando
| Lo que sigue mal | Se arregla en |
|---|---|
| Al reiniciar se pierde todo | UD5, con PostgreSQL |
| Buscar recorre la lista entera, una por una | UD5, con consultas |
| No hay forma de relacionar datos más allá de guardar un id | UD5, con relaciones |
| Nadie garantiza que dos operaciones simultáneas no se pisen | UD5, con transacciones |
Conviene observar lo que no aparece en esa tabla: ni el contrato, ni las reglas, ni la estructura. Eso ya está.
Por qué la UD5 va a ser más fácil de lo que parece
Tu service pide una interfaz. En la UD5 se borra la implementación en memoria y se pone otra que habla con PostgreSQL.
El service, el controller, los DTO, el mapper y los tests no se tocan. Cambiar la base de datos entera va a ser un cambio localizado, y eso es exactamente lo que has construido estas dos semanas.
Ver respuestas
1 · Porque deja dos formas de hacer lo mismo conviviendo, y quien llegue después no sabrá cuál es la buena ni por qué hay dos.
2 · La colección demuestra que el comportamiento observable no ha cambiado. Los tests demuestran que las reglas de negocio siguen siendo las decididas, y lo seguirán demostrando en el futuro.
3 · La implementación del repositorio. El service, el controller, los DTO, el mapper y los tests se quedan como están.
4 · El coste real de mantener el código: cuántos archivos hay que abrir y cuánto se tarda en un cambio pequeño, comparado con lo que costaba antes.
Paso 7 · Comprobar y registrar el resultado del proyecto
- Los tests del servicio y la colección deben pasar después de la revisión sin cambiar el contrato acordado.
- Pide a otra persona que localice almacenamiento, regla y respuesta de una operación. Registra cualquier dependencia entre capas que aún debas corregir.
Cierre
15 minutos · resultado comprobable y explicación individual
Al terminar la sesión:
La versión en capas supera las comprobaciones anteriores y permite justificar la ubicación de cada regla.
Cada integrante explica una decisión del código apoyándose en una de las comprobaciones realizadas.