现在我正在测试和重构代码,与此相关的是关于 Symfony 中应用程序正确架构的几个问题。
控制器的任务很明确,你需要接受参数,将它们传递给服务,在那里处理逻辑并将结果返回给控制器。但通常在服务逻辑中,您需要从数据库中计算出数据。因此,就有一个问题,是否可以在服务中调用数据库呢?我几乎在每个服务中都注入了对实体管理器或某些存储库的依赖,这正常吗?或者值得在控制器中完成所有这些工作吗?是否可以将数据保存到服务中的数据库中?我有一个付款服务,我在其中进行所有检查,然后将付款保存到数据库中。当然,所有这些都可以通过控制器来完成,甚至更容易(不需要注入不必要的依赖),但是你不能没有 if, else 结构。
同样的问题可以应用于事件侦听器和处理程序。我每次都会检查用户还剩多少付费天数。为此,我在观察者中多次访问数据库。
我做得对吗?还是仍然值得严格限制服务和控制器的功能?我会很高兴得到任何提示。
使控制器变薄是在做正确的事。控制器是 HTTP 层,它可能的任务是解析请求参数(如果它们尚未在路由阶段解析)和格式化响应(就数据格式而言 - HTML、JSON 等)。
一般来说,是的,这是很正常的。但不可能给出明确的答案:它在很大程度上取决于您的应用程序的具体情况、主题领域和总体架构。
服务的功能应限于其任务(您的 Q.O.)。记住单一职责,不要创建上帝对象。将服务分层,将通用功能移动到单独的库/组件中。
Symfony 分离逻辑的良好实践是一般软件开发的良好实践,像这样的建议只能是尽可能的通用。例如,您可以遵循DDD模式。你可以读读福勒。有“官方”的Symfony Best Practices。我还可以推荐 Doctrine 维护者提供的关于ORM 良好实践的材料。
阅读,选择最适合你的。
如果项目不是太复杂,那么从DB-repositories中获取实体做一个单点是最方便的。
存储库可以做什么:
$em->flush存储库不应包含与数据库没有直接关系的复杂逻辑。它进入服务。
依赖服务可以有一个存储库,如果需要,还可以有一个 EntityManager。
如果控制器只需要从表单中获取数据并保存,则它们会与存储库和 EntityManager 进行通信。如果你需要更复杂的逻辑,那么通过服务。
这种方法适用于大多数典型项目。