Consolidar código duplicado preservando las reglas de negocio
Dos métodos similares no representan necesariamente una sola regla. Los procesadores de pedidos y devoluciones comparten mecanismos de validación, pero usan distintos prefijos, umbrales de envío y sentidos de actualización del inventario. Eliminar esas diferencias sería un cambio de comportamiento.
Resumen del laboratorio

Ilustración conceptual original (SVG)
| De un vistazo | Tu ruta |
|---|---|
| Nivel y tiempo | 200; 55 minutos (estimación de facilitación) |
| Acción inicial | Captura los umbrales de igualdad antes de extraer un helper. |
| Materiales del aprendiz | Descarga 07-duplication.zip |
| Espacio de trabajo | Abre la raíz del kit extraído; ejecuta la baseline desde . relativa a esa raíz |
| Comprobación inicial esperada | El proyecto seleccionado compila. La compilación por sí sola no prueba el comportamiento. |
| Ayuda de configuración | Descarga, extrae, Git local y GitHub opcional |
[!NOTE] Un código similar no significa la misma política de envío o inventario.
Conceptos · Primera tarea · Lista de evidencias · Restablecer
Objetivos de aprendizaje
- Identifica duplicación exacta frente a semántica usando código real.
- Captura las salidas y los efectos secundarios actuales antes de extraer.
- Elige una pequeña abstracción compartida sin generalizar en exceso las políticas.
- Detecta una refactorización que cambie accidentalmente un límite.
Antes de empezar
Prepara 07-duplication con la configuración común.
La fuente es el
fixture ECommerceOrderAndReturn incluido.
Usa su destino de SDK de .NET y un solo proceso de compilación.
Conceptos y casos de uso
| Candidato | Posible mecanismo compartido | Mantener explícito |
|---|---|---|
Validate |
Comprobaciones de vacío y longitud | Prefijos ORD frente a RET |
CalculateShipping |
Aplicar una política | Umbrales e importes de pedidos y devoluciones |
| Notificaciones | Formato y salida | Propósito del mensaje y destinatarios |
| Inventario | Límites y registro | Reservar disminuye; restituir aumenta |
Los procesadores capturan y registran excepciones. Por tanto, un código de salida cero de la demostración no demuestra que se haya lanzado una excepción esperada. Este es un ejercicio de caracterización, no una prueba de seguridad de producción.
Escenario del ejercicio
Debes reducir la duplicación de mantenimiento sin cambiar los totales, el inventario, los mensajes de validación ni el orden de eventos. Un cambio de negocio separado necesitaría sus propios criterios de aceptación y revisión.
Tarea 1 - Capturar una línea base real
-
Lee
OrderProcessor.cs,ReturnProcessor.cs,Configuration/AppConfig.csy los servicios a los que llaman. -
Compila el proyecto copiado:
dotnet build ECommerceOrderAndReturn.csproj -m:1 -p:UseSharedCompilation=false dotnet run --no-build --project ECommerceOrderAndReturn.csproj -
Registra los totales actuales de envío de pedidos y devoluciones, el inventario antes y después y los IDs rechazados. Trata
EXPECTED_OUTPUT.mdcomo una ilustración histórica, no como la salida de hoy. -
Identifica las marcas de tiempo o los identificadores generados antes de comparar registros. No elimines valores de negocio solo para hacer que un diff parezca igual.
Tarea 2 - Analizar la duplicación con Ask
Compare OrderProcessor.Validate and ReturnProcessor.Validate. Cite the shared
mechanics and the policy differences. Do the same for shipping and inventory.
Do not edit. Flag swallowed exceptions separately from the refactoring scope.
Comprueba la respuesta frente a estas reglas concretas de envío:
| Regla | Pedidos | Devoluciones |
|---|---|---|
| Base | 5.00 | 3.00 |
| Recargo por peso | Más de 10: +2.00 | Más de 5: +1.50 |
| Descuento por valor | Más de 50: -1.00 | Más de 30: -0.50 |
| Tratamiento especial | Frágil: +3.00 | Sobredimensionado: +4.00 |
No sustituyas «más de» por «al menos». Prueba valores inmediatamente por debajo, iguales y por encima de los umbrales antes de mover código.
Tarea 3 - Planificar una extracción
- En Plan, elige validación o envío para el primer cambio.
- Exige una tabla de reglas preservadas, parámetros propuestos, llamadores existentes, casos de regresión y reversión.
- Explica por qué un auxiliar compartido es más sencillo que una nueva jerarquía de clases.
- Conserva los métodos públicos originales de procesamiento y el orden de efectos secundarios.
- Define un punto de detención tras una extracción que preserve el comportamiento.
Tarea 4 - Implementar y cuestionar el resultado
- Pide a Agent que implemente únicamente esa extracción.
- Inspecciona todos los llamadores; los auxiliares sin uso no constituyen consolidación.
- Añade aserciones sobre valores deterministas o un harness de caracterización de alcance reducido. No rebautices una transcripción de consola como «pruebas unitarias».
- Vuelve a ejecutar la misma compilación y demostración y las aserciones añadidas.
- Invierte temporalmente un umbral en la copia desechable. Confirma que falle la aserción pertinente y después restáuralo.
- Considera una segunda extracción solo después de verificar la primera.
Verifica tu trabajo
- Los puntos de entrada públicos y las reglas observables permanecen sin cambios.
- Se prueban los límites de igualdad de peso y valor.
- Reservar y restituir siguen teniendo efectos opuestos sobre el inventario.
- Las nuevas aserciones rechazan un umbral intencionalmente incorrecto.
- El diff contiene reutilización real y no una abstracción sin uso.
Solución de problemas
| Síntoma | Causa probable |
|---|---|
| Cada ejecución tiene un registro diferente | Hora o IDs dinámicos; compara explícitamente los campos estables |
| Los precios de pedidos y devoluciones convergen | Se fusionaron accidentalmente políticas distintas |
| Todos los escenarios de demostración terminan con cero | Las excepciones se registran internamente; añade aserciones que detecten errores |
| La refactorización se extiende por muchas capas | Vuelve a una extracción y declara los objetivos excluidos |
Práctica independiente
Refactoriza un auxiliar de notificaciones conservando los métodos y mensajes públicos. Explica por qué cambiar el comportamiento de reintentos sería una función separada.
Restablecimiento
Detén la demostración, guarda la línea base y la evidencia de comparación y restaura únicamente los archivos nombrados del ejercicio en la copia desechable. No sobrescribas el fixture fuente.