Refactorizar una función grande sin perder las rutas de error
Un método más corto no es automáticamente más seguro. Extraer un paso de pago puede sacar la limpieza del inventario de la ruta de fallo. Tu evidencia debe cubrir los fallos y los efectos secundarios, no solo el pedido exitoso.
Resumen del laboratorio

Ilustración conceptual original (SVG)
| De un vistazo | Tu ruta |
|---|---|
| Nivel y tiempo | 300; 60 minutos (estimación de facilitación) |
| Acción inicial | Traza el éxito y el fallo antes de elegir el límite de extracción. |
| Materiales del aprendiz | Descarga 08-functions.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 de entrada de consola compila; el comportamiento de la compensación necesita afirmaciones separadas. |
| Ayuda de configuración | Descarga, extrae, Git local y GitHub opcional |
[!NOTE] Un rechazo de pago no debe dejar el inventario reservado incorrectamente.
Conceptos · Primera tarea · Lista de evidencias · Restablecer
Objetivos de aprendizaje
- Descompón un método largo en responsabilidades y transiciones de estado.
- Conserva el orden, los mensajes de error y la compensación durante la extracción.
- Prefiere una extracción ejecutable a una colección de esqueletos sin uso.
- Revisa el comportamiento antes y después de forma independiente de la explicación del agente.
Antes de empezar
Prepara 08-functions usando la guía del entorno.
Usa el
fixture ECommerceOrderProcessing incluido.
Todos los pagos, direcciones y notificaciones son sintéticos.
Conceptos y casos de uso
| Concepto | Por qué importa |
|---|---|
| Cohesión | Un método extraído debe tener una responsabilidad significativa |
| Contrato | Los parámetros y resultados expresan lo que debe sobrevivir a una extracción |
| Compensación | Deshacer una reserva cuando falla un paso posterior |
| Orden | Mover llamadas de auditoría o inventario cambia el comportamiento observable |
| Caracterización | Las pruebas registran el comportamiento actual antes de una refactorización |
Escenario del ejercicio
OrderProcessor.ProcessOrder coordina la validación, el inventario, el pago, el envío,
las notificaciones y la salida de auditoría. Conserva el comportamiento existente mientras facilitas
la inspección de cada paso.
Tarea 1 - Rastrear el método existente
-
Lee
src/ECommerce.ApplicationCore/Services/OrderProcessor.cs, sus interfaces y las implementaciones desrc/ECommerce.Infrastructure/Services. -
En Ask:
Trace ProcessOrder from input validation to completion. For each exit path, list changed state, audit events, inventory release, and the returned result. Cite the implementation rather than assuming the interface guarantees it. -
Anota la siguiente secuencia conceptual contrastándola con el código fuente real.
---
config:
theme: base
look: classic
themeVariables:
darkMode: false
background: "#ffffff"
primaryColor: "#f5f5f5"
primaryTextColor: "#111111"
primaryBorderColor: "#555555"
secondaryColor: "#e0e0e0"
secondaryTextColor: "#111111"
secondaryBorderColor: "#666666"
tertiaryColor: "#bdbdbd"
tertiaryTextColor: "#111111"
tertiaryBorderColor: "#444444"
lineColor: "#444444"
textColor: "#111111"
mainBkg: "#f5f5f5"
nodeBorder: "#555555"
clusterBkg: "#ffffff"
clusterBorder: "#999999"
edgeLabelBackground: "#ffffff"
actorBkg: "#e0e0e0"
actorBorder: "#555555"
actorTextColor: "#111111"
actorLineColor: "#777777"
signalColor: "#333333"
signalTextColor: "#111111"
labelBoxBkgColor: "#f5f5f5"
labelBoxBorderColor: "#777777"
labelTextColor: "#111111"
loopTextColor: "#111111"
activationBkgColor: "#bdbdbd"
activationBorderColor: "#555555"
noteBkgColor: "#f5f5f5"
noteTextColor: "#111111"
noteBorderColor: "#777777"
attributeBackgroundColorOdd: "#f5f5f5"
attributeBackgroundColorEven: "#e0e0e0"
---
sequenceDiagram
accTitle: Límite de compensación del procesamiento de pedidos
accDescr: Una reserva precede al pago; un pago rechazado debe liberar la reserva antes de devolver un resultado de fallo.
participant Caller
participant Processor
participant Inventory
participant Payment
Caller->>Processor: ProcessOrder
Processor->>Inventory: Reservar existencias
Inventory-->>Processor: Resultado de la reserva
Processor->>Payment: Intentar el pago
alt Pago aceptado
Payment-->>Processor: Aceptado
Processor-->>Caller: Continuar el flujo documentado
else Pago rechazado
Payment-->>Processor: Rechazado
Processor->>Inventory: Liberar la reserva
Processor-->>Caller: Resultado de fallo y evidencia de auditoría
end
Leyenda. Los encabezados de participantes identifican a los colaboradores. Las flechas continuas son llamadas;
las discontinuas son respuestas. Las ramas alt distinguen el éxito del rechazo.
Explicación. Este diagrama destaca la obligación de compensar. Complétalo a partir de las ramas de envío y notificación del fixture antes de tratarlo como un modelo completo; no es una traza de contacto real con un servicio de pago.
Tarea 2 - Establecer evidencia de las ramas
-
Compila únicamente el proyecto de consola:
dotnet build src/ECommerce.Console/ECommerce.Console.csproj -m:1 -p:UseSharedCompilation=false dotnet run --no-build --project src/ECommerce.Console/ECommerce.Console.csproj -
Registra los resultados de pedido válido, correo no válido, pago rechazado y pedido sospechoso.
-
Inspecciona el archivo de auditoría generado en el directorio de trabajo del proceso.
-
Distingue los campos de negocio de las marcas de tiempo. No deben usarse marcas de tiempo de transcripciones antiguas ni fechas de caducidad de tarjetas de ejemplo como resultados esperados actuales.
-
Añade una aserción sobre la liberación de la reserva ante un pago rechazado. Si la demostración existente solo muestra resultados, un código de salida cero no es evidencia suficiente.
Tarea 3 - Diseñar una extracción acotada
Usa Plan:
Extract only payment processing and its documented compensation boundary.
Preserve public signatures, result semantics, audit order, and inventory release.
List tests for acceptance, rejection, and failure before reservation.
Do not add retry, concurrency, or exception-swallowing fallbacks.
Revisa dónde permanece la responsabilidad de la limpieza. Rechaza una extracción que haga que tanto el llamador como el auxiliar liberen la misma reserva.
Tarea 4 - Implementar una parte
- Pide a Agent que realice la extracción planificada y actualice los llamadores.
- Inspecciona todo el diff, especialmente los retornos anticipados y los bloques
finally. - Ejecuta las mismas comprobaciones y tu aserción de compensación.
- Omite temporalmente la llamada de liberación. Confirma que la aserción falle y después restáurala.
- Solo entonces considera extraer la validación o el envío como otra parte.
Verifica tu trabajo
- Los escenarios existentes conservan su semántica de resultados.
- Un rechazo de pago libera una reserva exactamente como antes.
- Un fallo anterior a la reserva no realiza una compensación inapropiada.
- Se explica y verifica el orden de los eventos de auditoría.
- Se detecta una mutación negativa.
Solución de problemas
Si desaparecen excepciones, compara los límites de error en lugar de añadir una captura general. Si el inventario difiere, comprueba si hay una doble liberación o cambios en el orden de llamadas. Si el método se acorta, pero las responsabilidades siguen acopladas mediante muchos parámetros de salida, revisa la abstracción en lugar de contar líneas.
Práctica independiente
Aplica el enfoque a ServerLogAnalysisUtility, incluido, en una copia separada. Especifica la codificación de archivos, el comportamiento ante líneas mal formadas y el orden de salida antes de extraer.
Restablecimiento
Detén el proceso de consola, guarda la evidencia y restaura únicamente los archivos fuente y de pruebas nombrados en la copia desechable. Elimina solo el archivo de auditoría generado por esa copia.