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 实体)。
很想听听关于此事的其他意见。
干杯
我正在努力完成以下任务:
我有一个 "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 实体)。
很想听听关于此事的其他意见。
干杯