【问题标题】:how to model an entity's property in DDD如何在 DDD 中为实体的属性建模
【发布时间】:2020-05-12 00:04:07
【问题描述】:

我有一个Survey 模型类,它有以下四个值对象:

  • id
  • creationDate
  • comment
  • answeredDate

调查会在固定时间后到期,比如 48 小时。然后我需要对此进行建模,但我不知道将它放在哪里。

  • creationDate 上像hasExpired(now: Date) 一样的方法?
  • 作为实体本身的函数,检查creationDate?
  • 其他解决方案?

【问题讨论】:

  • 您可能还想以不同的方式处理此问题。如果您希望应用程序对调查过期的事实做出反应怎么办?也许有一个调查到期政策会触发一个转换调查状态的事件?
  • 您可能会觉得这很有趣。 kalele.io/modeling-temporal-occurrences
  • 还有一个关于建模到期的老问题。也许它会激发想法。 stackoverflow.com/questions/40288764/…
  • 您可以按照在 JSON Web Token 中建模的方式来处理它。只需将到期日期时间存储为实体的属性。然后关心的人会适当地使用它。因为调查是否过期本身并不重要,而是在某些操作的背景下。例如。提交已过期。然后“提交”命令处理器应该关心。
  • @iTollu “调查已过期本身并不重要”。这当然取决于域。您可能希望基于该事实来限制操作,但您也可以很好地触发操作。例如,“当调查到期时,向调查的创建者发送通知”。

标签: domain-driven-design


【解决方案1】:

我不知道您正在编写哪种语言,但我将提供一些 C# 示例代码,但我认为它足以说明我的意思。我建议您在创建对象后计算并保留过期时间,因为您可以使用此属性来根据过期时间查询您的存活时间。

public class Survey 
{
    public DateTime CreationDate{get; private set;}
    public DateTime ExpireDate{get; private set;}
    public Survey(...,DateTime creationDate,..)
    {
     //Validations...
     //Some Property Initialization
     this.CreationDate=creationDate
     this.ExpireDate=creationDate.AddHoure(48)

    }
}

现在您可以将业务规则抽象为规范,在您的情况下:“如果过期时间已过,则调查已过期”。我将通过一个示例向您展示我的意思:

public class TheSurveyHasBeenExpiredSpecification:Specification<Survey>
{
public Expression<Func<Survey , bool>> Expression => x=> x.ExpireDate <= DateTime.Now;
public bool IsStifiedBy(Survey entity)
{
return Expression.Compile().Invoke(entity);
}
}

现在您可以享受规范的乐趣了,您可以将其与 ORM 一起使用以检索过期的调查记录,也可以在代码中使用它来决定调查是否过期 在我的示例中,您应该将实体传递给“IsStifiedBy “ 方法。 祝你好运

【讨论】:

    【解决方案2】:

    解决方案 1

    选项一和二的混合,这里是一个伪代码:

    class Survey {
      public bool hasExpired(now: Date) {
        creationDate.modify('+48 hours').isLessThan(now);
      }
    }
    

    解决方案 2

    您也可以寻求不同的解决方案。您的聚合应该有 lifetime 字段,该字段将在创建调查时给出。此解决方案将为您提供极大的灵活性。

    假设您开始项目时,Survey 的默认生命周期为 48 小时。所以所有新的调查都有 48 小时的生命周期。但与此同时,企业希望将其更改为 7 天。

    现在使用以前的解决方案,您遇到了问题。尚未过期或刚刚过期的当前调查怎么办?

    我认为在更改之前创建的调查应该还有旧的生命周期(48 小时)。如果您在调查中设置了生命周期,那么您对此没有任何问题。旧调查仍将有 48 小时,但新调查将有 7 天。您只需要在方法hasExpired(now: Date) 中使用生命周期字段。

    解决方案 3

    还有第三种解决方案。它被称为策略。策略可以封装计算调查生命周期的逻辑。所以你可以有不同的政策。这将为您提供更大的灵活性。

    【讨论】:

    • 好点。 “+48 小时”呢?我将它定义为类的常量,以避免幻数。但我不知道这是否是最佳做法
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2011-05-04
    相关资源
    最近更新 更多