DDD временной переход между состояниями
У меня есть совокупный корень с объектом значения "startTime". В разные моменты мне нужно определить, "начал" ли AR, чтобы навязать другое поведение (как внутренне, так и внешне по отношению к AR). Мне также нужно иметь возможность фильтровать агрегатные корни на уровне хранилища по их "запущенному" состоянию из соображений производительности.
Я не уверен, как реализовать это в удобной для DDD форме. Я рассмотрел возможность выставить изменение состояния внешнему источнику (обработчику запланированного события) и определить состояние явно:
public class AggregateRoot {
private Time startTime;
private boolean started;
...
public void start() {
started = true;
}
public boolean isStarted() {
return started;
}
}
Преимущество этого заключается в простоте запроса на уровне хранилища, но кажется странным, так как объект значения startTime становится избыточным, и в домене нет ничего, что могло бы навязать состояние переключения AR в определенном startTime.
Я также рассмотрел возможность неявного определения состояния на основе сравнения "сейчас" с "startTime" (либо при построении AR, либо при получении, например, при получении). Это означает, что AR полностью контролирует свое собственное состояние и т. Д., Но означает, что я не могу фильтровать запросы на уровне хранилища по состоянию без дублирования этой логики (плохо для удобства обслуживания):
public class AggregateRoot {
private Time startTime;
...
public boolean isStarted() {
return now().isAfter(startTime);
}
}
Существуют ли шаблоны для обработки изменений состояния по времени? Есть ли лучший способ приблизиться к этому?
1 ответ
Интересно. Я ничего не знаю о вашем домене, но мне интересно, насколько отличается поведение вашего агрегата после его запуска? Возможно ли, что на самом деле у вас есть два разных агрегата, которые зависят от одного и того же состояния? Вместо того, чтобы помещать это поведение в саму совокупность, можно ли извлечь ее из - я осмелюсь предложить это - фабрику?
public class MyAggregateBeforeItHasStarted : IMyTemporalAggregate
{
public MyAggregateBeforeItHasStarted(State state) { }
}
public class MyAggregateAfterItHasStarted : IMyTemporalAggregate
{
public MyAggregateAfterItHasStarted(State state) { }
}
public class MyTemporalAggregateFactory
{
public IMyTemporalAggregate(StartTime startTime)
{
if (startTime.LaterThan(x))
return new MyAggregateAfterItHasStarted(state);
return new MyAggregateBeforeItHasStarted(state);
}
}