【问题标题】:symfony 3.4 business logic in AppBundle\Utils [closed]AppBundle\Utils 中的 symfony 3.4 业务逻辑 [关闭]
【发布时间】:2019-01-27 05:01:48
【问题描述】:

我是 symfony 的新手,我正在阅读这里的最佳实践指南 https://symfony.com/doc/3.4/best_practices/business-logic.html

我有一个名为 Category 的控制器,我有这个操作方法来列出类别。

public function listCategory(Request $request, CategoryLogic $categoryLogic)
{
    $categories = $categoryLogic->getAllCategory($this->getDoctrine());

    return $this->render('listCategory.html.twig', ['categories' => $categories]);
}

如您所见,我所有的控制器业务逻辑都转到 -> AppBundle\Utils\CategoryLogic

我有这个方法来处理逻辑并返回类别

use AppBundle\Entity\Category; 

/**
 * @param Registry $doctrine
 * @return array
 */
public function getAllCategory(Registry $doctrine)
{
    $repositoryCategory = $doctrine->getRepository(Category::class);
    $category = $repositoryCategory->findAll();

    return $category;
}

目的是保持控制器清洁。这是最好的方法吗?我有点担心将逻辑类命名为 CategoryLogic 相反,我想将其命名为 Category,但是我遇到了另一个问题,因为我已经在 CategoryLogic 类中导入了use AppBundle\Entity\Category,所以不能有两个 Category 类

【问题讨论】:

  • 在 Symfony 中有很多处理业务逻辑的方法,“最好的方法”取决于你的偏好。您可以将其编写为服务、控制器事件、模型中、单独的模型或实体存储库方法。最终,这将是您认为满足您需求的最佳方法。然而,对于这一点,教义通过$categories = $em->getRepository(Category::class)->findAll(); 满足您的业务逻辑,并且会更加优化。但是,如果您有 return $a + $b 这样的条件,我会使用服务、模型或存储库。
  • @fyrye 你能举一个服务、模型或存储库的例子吗?是否将 Utils 视为服务?
  • @dev1234 您链接的“最佳实践”页面应该谨慎对待。那里有几个好主意,但不要从字面上理解所有内容。使用常识和常见的软件开发最佳实践。
  • @dev1234 由于您是 Symfony 的新手,我强烈建议您浏览一些教程,例如 KnpUniversity 上的教程并学习 Doctrine best-practices by Ocramius。找出最适合 和您的应用程序需求的方法。您的问题只会为您提供没有单一正确答案的固执己见的答案,而不会针对每种方法写一篇文章,这更像是一个教程而不是一个答案。例如,我强烈反对当前的答案,因为它会导致不必要的腹胀

标签: php symfony symfony-3.4


【解决方案1】:

对于您的具体示例,当您可以在控制器中注入 Repository 时,使用 Util 类是没有用的。

public function listCategory(Request $request, CategoryRepository $categoryRepository)
{
    $categories = $categoryRepository->findAll();

    return $this->render('listCategory.html.twig', ['categories' => $categories]);
}

从 symfony 3.3 开始,它具有依赖注入,这意味着您可以将服务注入其他服务。如果你想用一些服务来处理它,例如Utils,你可以这样弄。

//CategoryController.php

public function listCategory(Request $request, CategoryService $categoryService)
{
    $categories = $categoryService->getAllCategories();

    return $this->render('listCategory.html.twig', ['categories' => $categories]);
}

//CategoryService.php

namespace App\Service;

use App\Repository\CategoryRepository ;

class CategoryService 
{
    private $categoryRepository;

    // We need to inject these variables for later use.
    public function __construct(CategoryRepository $categoryRepository)
    {
        $this->categoryRepository = $categoryRepository;
    }

    public function getAllCategories()
    {
        $categories = $this->categoryRepository->findAll();

        return $categories;
    }
}

始终使用单数和复数名称来排除混淆,例如$category 将有一个 Category 对象,而 $categories 将是 Category 对象的数组,或者至少是 Category 对象的 Iteratable (Collection) 对象。当您稍后尝试调试代码并帮助其他人更好地理解您的代码时,它将使您的生活变得轻松。

附录:

https://symfony.com/doc/current/doctrine.html#querying-for-objects-the-repository https://symfony.com/doc/current/service_container/3.3-di-changes.html https://symfony.com/doc/current/service_container/injection_types.html

【讨论】:

  • 使用存储库我们如何保存记录?这就是我保存记录的方式 $em = $doctrine->getManager(); $em->persist($category); $em->flush();
  • 这是我尝试使用您的方式时遇到的错误“控制器”AppBundle\Controller\CategoryController::listCategory()”要求您为“$categoryRepository”参数提供一个值
  • 在控制器和实体之后。您创建服务的一切。例如您使用存储库来获取实体的数据,Repo 是一项服务。您创建一个用于发送电子邮件或 pdf 的 lib 类,它将是一项服务。您可以在控制器或其他服务中注入这些服务。
  • @dev1234 但是,您应该/不需要将实体转换为服务,而是使用SensiFrameworkExtraBundle ParamConverter,它为理论实体提供 DI 行为。
  • @Cerad 虽然您对 Symfony 4+ 是正确的,但这个问题是关于 Symfony 3.4,在 Symfony Standard 中默认情况下不包括存储库目录,如我发布的链接中所引用的。我确实没有提到扩展ServiceEntityRepository 而不是EntityRepository,它在Symfony 3.4 中也可以使用DoctrineBundle 1.8+,由于Symfony Standard 的作曲家规则,它应该在作曲家更新期间安装。尽管如此,您可以在 3.4 中将存储库原型化为服务,但默认情况下不能。
猜你喜欢
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
  • 2018-07-30
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多