【问题标题】:Change entity status depending on datetime value根据日期时间值更改实体状态
【发布时间】:2019-12-28 17:15:36
【问题描述】:

我有一个 Subscription 实体,它具有 status 和 canceledAt 字段。

当canceledAt 过期时,我希望status 从active 更改为canceled。

所以,我想在 Subscription::getStatus 方法中检查 cancelledAt:

// Subscription.php

public function getStatus()
{
     // .... check canceledAt

     return $this->status;
}

但这也需要更改 persistence 层的状态。

我应该对事件做些什么吗?

【问题讨论】:

    标签: php domain-driven-design hexagonal-architecture


    【解决方案1】:

    如果您不将时间视为输入值,请考虑它直到您这样做 - 这是一个重要的概念 -- John Carmack, 1998

    对于一个简单的查询,处理这个问题的直接方法是将当前时间作为输入传递

    // Subscription.php
    
    public function getStatus(currentTime)
    {
        // .... check canceledAt
        if (currentTime > canceledAt) {
            // ....
        }
    
        return $this->status;
    }
    

    另一方面,如果您试图做的是影响状态的权威更改,那么您将在 命令中将当前时间传递给您的域模型。

    public function onTick(currentTime) {
        // ....
    }
    

    在某些情况下,通过时钟的域服务表示而不是值来表示时间可能是有意义的。重要的一点是应用程序,而不是领域模型,负责“现在几点?”

    【讨论】:

      【解决方案2】:

      最后,我创建了一个应用程序服务来获取订阅状态,以便我可以将其存储在数据库中以备不时之需。

      此外,我从Subscription 实体中删除了getStatus 方法。

      【讨论】:

        【解决方案3】:

        我不会坚持任何状态。只是被取消的日期时间。为什么?因为状态取决于当前日期时间。您现在可以保留一个状态值,但该值可能是错误的,例如下一分钟。然后,从下一分钟及以后,您将持续存在错误的值。

        在我看来,持久化一个随时间变化的值是没有意义的,因为持久化的含义恰恰相反,是存储一个本身不会改变的值。

        我会在请求时计算状态,具体取决于当前日期时间和取消时间,但我不会坚持下去。由于它取决于当前日期时间,您应该将当前日期时间视为输入值,就像@VoiceOfUnreason 在他的回答中所说的那样。

        【讨论】:

          猜你喜欢
          • 2017-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-24
          • 1970-01-01
          • 1970-01-01
          • 2020-05-01
          相关资源
          最近更新 更多