2

我有一个带有“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 切换状态。

我还考虑过基于“现在”与“开始时间”的比较隐式定义状态(在 AR 构造或 getter 上,示例在 getter 上)。这意味着 AR 完全控制自己的状态等,但这意味着我无法在不复制此逻辑的情况下按状态过滤存储层的查询(不利于可维护性):

public class AggregateRoot {
    private Time startTime;
    ...
    public boolean isStarted() {
        return now().isAfter(startTime);
    }
}

是否存在处理基于时间的状态变化的现有模式?有没有更好的方法来解决这个问题?

4

1 回答 1

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);
    }
}
于 2014-05-30T20:43:49.490 回答