DDD - 使可过期无效

时间:2013-01-04 20:51:39

标签: domain-driven-design

目前正在深入研究DDD,我已经阅读了Eric Evans的大部分蓝皮书。到目前为止非常有趣:)

我一直在为一些聚合建模,在这些聚合中他们拥有一系列过期的实体。我想出了一种表达的通用方法:

public class Expirable<T>
{
    public T Value { get; protected set; }
    public DateTime ValidTill { get; protected set; }

    public Expirable(T value, DateTime validTill)
    {
        Value = value;
        ValidTill = validTill;
    }
}

我很好奇最好的方法是使Expirable无效(在集合中工作时无效或省略它)。到目前为止,我一直在考虑在Repository构造函数中执行此操作,因为这是您从中访问聚合的位置,并充当“集合”。

我很好奇是否有人提出解决方案来解决这个问题,我很乐意听到它:)其他方法也非常受欢迎。

更新10-1-2013:

这不是来自Greg Young的CQRS / ES方法的DDD。但是埃文斯的方法,因为我刚开始使用这本书和第一个应用程序。就像Greg Young说的那样,如果你必须做好桌子,你必须先做一些;)

3 个答案:

答案 0 :(得分:1)

可能有多种方法可以解决这个问题,但我个人会使用规范模式来解决这个问题。假设对象到期是属于域的业务规则,除了您编写的类之外,我还有一个规范。这是一个例子:

public class NotExpiredSpecification
{
    public bool IsSatisfiedBy(Expirable<T> expirableValue)
    {
        //Return true if not expired; otherwise, false.
    }
}

然后,当您的存储库返回聚合列表或在集合上执行任何业务操作时,可以利用此限制将集合限制为未过期的值,这将使您的代码具有表现力并将业务逻辑保留在域。

要详细了解规范模式,请参阅this paper

答案 1 :(得分:0)

我在我的抽象存储库InvalidateExpirable中添加了一个方法。一个示例是UserRepository我在活动用户会话中删除的内容如下:InvalidateExpirable(x => x.Sessions, (user, expiredSession) => user.RemoveSession(expiredSession));

InvalidateExpirable的签名如下所示:protected void InvalidateExpirable<TExpirableValue>(Expression<Func<T, IEnumerable<Expirable<TExpirableValue>>>> selector, Action<T, Expirable<TExpirableValue>> remover)。该方法本身使用反射从selector参数中提取selected属性。该属性名称粘贴在一个通用的HQL查询中,该查询将遍历调用remove lambda的集合。 user.RemoveSession将从聚合中删除会话。这样我保持聚合对它自己的数据负责。同样在RemoveSession中,将针对未来案例引发域事件。

请参阅:https://gist.github.com/4484261以获取示例

非常好用,我必须看看它在应用程序中的工作原理如何。

答案 2 :(得分:0)

一直在阅读使用CQRS / ES(Greg Young方法)的DDD,并在MSDN网站上找到了关于CQRS / ES的一个很好的例子:http://msdn.microsoft.com/en-us/library/jj554200.aspx

在此示例中,他们使用命令消息队列在将来对Expire消息进行排队,该消息将在指定时间调用Aggregate从聚合中删除/停用可过期构造。