Але що робити, якщо одна з подій повинна призвести до того, що зовнішня система, яка не перебуває у вашому контролі, "відправить товар" замовнику, якщо ви просто повторите події, предмет буде доставлений двічі.
Щоб вибрати конкретний приклад, давайте розглянемо, як може «принаймні один раз» підійти до побічних ефектів.
State currentState = State.InitialState
for(Event e : events) {
currentState = currentState.apply(e)
}
for(SideEffect s : currentState.querySideEffects()) {
performSideEffect(s)
Отже модель домену відстежує, що потрібно зробити; але фактичне виконання залишає у додатку
У контексті виконання команди основна ідея виглядає однаково. Фактичні побічні ефекти трапляються поза транзакцією, яка оновлює модель.
Тож одиничні тести для вашої моделі можуть виглядати приблизно
{
// 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()
}
Тут є основні моменти
- Оновлення моделі не має побічних ефектів; фактичні побічні ефекти трапляються поза транзакцією, яка оновлює модель.
- Подія, що описує результат побічного ефекту, повинна повернутися.