Pero, ¿qué pasaría si uno de los eventos causara que un sistema externo que no esté bajo su control "envíe un artículo" al cliente si solo repite los eventos, el artículo se enviará dos veces?
Para elegir un ejemplo específico, consideremos cómo podría funcionar un enfoque "al menos una vez" de los efectos secundarios.
State currentState = State.InitialState
for(Event e : events) {
currentState = currentState.apply(e)
}
for(SideEffect s : currentState.querySideEffects()) {
performSideEffect(s)
Entonces, el modelo de dominio rastrea lo que hay que hacer; pero deja el hacer real a la aplicación
En el contexto de ejecutar un comando, la idea básica se ve igual. Los efectos secundarios reales ocurren fuera de la transacción que actualiza el modelo.
Entonces, las pruebas unitarias para su modelo podrían verse más o menos así
{
// Given
State currentState = State.InitialState
// When
Events events = List.of(OrderPlaced)
// Then
List.of(SendEmail) === currentState.applyAll(events).querySideEffects()
}
{
// Given
State currentState = State.InitialState
// When
Events events = List.of(OrderPlaced, EmailSent)
// Then
List.EMPTY === currentState.applyAll(events).querySideEffects()
}
Los puntos principales aquí son
- La actualización del modelo no tiene efectos secundarios; Los efectos secundarios reales ocurren fuera de la transacción que actualiza el modelo.
- Un evento que describe el resultado del efecto secundario debe volver.