Symfony 3 - 关注点分离?

Symfony 3 - Separation of concerns?

我正在努力完成以下任务:

我有一个 "Sprint" 实体,其中包含许多 Ticket 实体。 每张票都有一个 TicketStatus(另一个实体)。

现在,在渲染 Sprint 时,我想计算 Sprint 的进度。

在哪里以及如何处理?

凭直觉,我会将其添加到我的 Sprint 实体的方法中(类似于 getSprintProgress())。

但是后来我到处读到,由于关注点分离,您不想查询实体中的数据库 class。

你会怎么做?

理想情况下,我会 运行 数据库上的 count() 查询...

这个问题有几种可能的解决方法。

首先,假设您已经定义了 Sprint 和 Ticket 实体之间的传统 Doctrine 关联,那么您的 Sprint::getProgress() 就可以了。门票将根据需要延迟加载。对于像这样简单的事情,这实际上是一个很好的起点。

您可以通过定义查询和预先加载票证来避免延迟加载的需要(并且可能会获得一些性能改进)。如果您小心的话,您可以优化查询,以便只加载所需的票证部分(可能是状态字段)。并且可能避免完全加载已关闭的工单。

另一种方法是将进度计算器移到它自己的 class。所以你可能有一个 SprintProgressCalculator::calculate($sprint) 方法。将其定义为服务并注入数据库连接。对于渲染,您可以将计算器注入到树枝扩展中并制作您自己的树枝函数。如果计算比简单查询更复杂,您可能会采用这种方法。

最后,只是一般性的观察,即 ORM 适用于基本的 CRUD 类型应用程序。与其说你参与了更多面向业务的运营,不如说是参与。因此,如果您确实有更多复杂的计算器和业务逻辑,那么您可能会考虑退回到简单的 sql.

目前我已经在我的 Sprint 实体中实现了这样的功能。

public function getProgress() {
  $tickets = $this->tickets;
  $done_tickets = $tickets->filter(function(Ticket $ticket) {
    return $ticket->getStatus()->getName() == 'Done';
  })->count();
return ($done_tickets / $tickets->count()) * 100;

让我澄清一下我在这里做了什么:

$this->tickets

包含一个 ArrayCollection。显然 ArrayCollections 有一个名为 filter 的方法,它允许定义一个闭包,我可以在其中做我想做的事。 有关 filter() 方法的更多信息 here

最后,我只计算该冲刺中已完成工单占工单总数的百分比。

这确实让我想知道两件事:

  • 来自 Laravel,他们使用 Fat Models,Slim Controllers 概念,感觉最 "natural"。但真的是这样吗?
  • 性能怎么样? $this->tickets 是否完整加载所有门票?因为我实际上只关心每张票所附的状态。 (顺便说一句,状态实际上是一个 TicketStatus 实体)。

很想听听关于此事的其他意见。

干杯