Symfony:使用服务返回实体是不好的做法?

时间:2017-03-30 13:38:57

标签: symfony doctrine

在我的项目中,我有:

  • Company实体:使用Doctrine
  • 创建
  • CompanyController:列出可以为公司实现的行动
  • CompanyManager服务:用于处理一些Company实体数据。

例如,Company实体具有getOpeningDays()功能,CompanyManager服务具有过滤假期的getRealOpeningDays()功能:

<?php
namespace AppBundle\Services\Company;

class CompanyManager
{

    private $em;
    private $companyBase;

    public function __construct(
        \Doctrine\ORM\EntityManager $em, 
        \AppBundle\Services\Work\PublicHolidays $publicHolidays
    ) { 
        $this->em               = $em;
        $this->publicHolidays   = $publicHolidays;
    }

    public function setCompanyId($companyId)
    {
        $this->companyBase = $this->em->getRepository('AppBundle:CompanyBase')->findOneBy(
            array('id' => $companyId)
        );
    }

    public function getRealOpeningDays()
    {
        // ...          
        foreach($publicHolidays as $publicHolidayKey => $publicHolidayData)
        {
            if(in_array($publicHolidayKey, $this->companyBase->getWorkedPublicHolidaysIds()) == false)
            {
                // ...
            }
        }
        return $publicHolidaysNonWorkedDates;
    }
}

在我的CompanyController中,有时我需要使用Company实体。

我现在想知道从Company服务返回此CompanyManager实体是否是一种不好的做法,在类似的功能中:

<?php
namespace AppBundle\Services\Company;

class CompanyManager
{

    //...

    public function getEntity()
    {
        return $this->companyBase;
    }
}

这将允许我改变这一点:

public function companySocialAction(Request $request)
{
    $session = $request->getSession();
    $companyBase = $this->getDoctrine()->getRepository('AppBundle:CompanyBase')->findOneBy(array('id' => $session->get('companyId')));

    $companyManager = $this->get('CompanyManager');
    $companyManager->setId($companyBase->getId());

    $form = $this->createForm(CompanySocialType::class, $companyBase);
    $form->handleRequest($request);


    // ...
}

在此:

public function companySocialAction(Request $request)
{
    $session = $request->getSession();

    $companyManager = $this->get('CompanyManager');
    $companyManager->setId($session->get('companyId'));

    $form = $this->createForm(CompanySocialType::class, $companyManager->getEntity());
    $form->handleRequest($request);

    // ...
}

谢谢。

1 个答案:

答案 0 :(得分:1)

这更像是一个代码审查问题,因此基于意见。但我希望,这很有帮助。但是,我会把它分成几部分:

CompanyManager

您的CompanyManagerEntityManager意义上的经理,就像您注入的那个(\Doctrine\ORM\EntityManager)?所以像find|findAll|persist|flush等所有方法都被包裹了?或者它更像是Factory还是更像是Symfony Provider?如果是这样,您可以将其命名为CompanyProvider,并且只应按照名称的建议进行命名。

Symfony已经为User实体使用了提供程序。该方案也可以用于其他实体:Create a User Provider

class CompanyProvider {
    public function loadCompanyById($id) {
        // […]

        if ($company) {
            return $company;
        }

        throw new CompanyNotFoundException(
            sprintf('Company with id "%s" does not exist.', $id)
        );
    }

    public function refreshCompany(\Company $company)
    {
        // […]
        return $this->loadCompanyById($company->getId());
    }
}

getRealOpeningDays()

我认为此方法不应该是提供Company实体的类的一部分。它看起来更像是一个实用程序或服务,也可用于其他实体或值。此功能也不明确 - 至少通过查看简化示例。它被称为getRealOpeningDays,但它返回一个名为publicHolidaysNonWorkedDates的东西。如果我找到了你,你可以创建一个这样的过滤器:

namespace AppBundle\Services;

class HolidayService {

    private $publicHolidays;

    public function __construct(\AppBundle\Services\Work\PublicHolidays $publicHolidays) {
        $this-> publicHolidays = $publicHolidays;
    }

    public function getPublicHolidays() {
        return $this->publicHolidays;
    }

    public function filterByPublicHolidays($datesOpen, $datesOpenOnHolidays = null) {
        // reduce $dateOpen by $this->publicHolidays
        // if $datesOpenOnHolidays is given, don't remove holidays that the company or any other entity is actually open
        return $collection;
    }
}

次要调整

  • 当方法setCompanyId从未实际设置公司ID时,不要调用方法companySocialAction,而是加载整个对象。
  • setId的第一个版本中,您将实体加载两次,这是不必要的。你可以简单地传递对象。 (我假设setCompanyId表示C:\yajsw-stable-12.08\bat>runConsole.bat C:\yajsw-stable-12.08\bat>pushd C:\yajsw-stable-12.08\bat\ C:\yajsw-stable-12.08\bat>call setenv.bat "java" -Xmx30m -Djna_tmpdir="C:\yajsw-stable-12.08\bat\/../tmp" -Djava.net.preferIPv4Stack=true -jar "C:\yajsw-stable-12.08\bat\/../wrapper.jar" -c "C:\yajsw-st able-12.08\bat\/../conf/wrapper.conf" YAJSW: yajsw-stable-12.08 OS : Windows 7/6.1/amd64 JVM : Oracle Corporation/1.8.0_121/C:\Program Files\Java\jre1.8.0_121/64 mar 30, 2017 3:54:18 PM org.apache.commons.vfs2.VfsLog info INFORMAZIONI: Using "C:\Users\Sexxa\AppData\Local\Temp\vfs_cache" as temporary files store. WARNING|wrapper|"WSO2 Carbon"|17-03-30 15:54:18|YAJSW: yajsw-stable-12.08 WARNING|wrapper|"WSO2 Carbon"|17-03-30 15:54:18|OS : Windows 7/6.1/amd64 WARNING|wrapper|"WSO2 Carbon"|17-03-30 15:54:18|JVM : Oracle Corporation/1.8.0_121/C:\Program Files\Java\jre1.8.0_121/64 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:19|started process with pid 18140 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:19|restart process due to default exit code rule INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:19|restart internal RUNNING INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:19|stopping process with pid/timeout 18140 45000 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:20|process exit code: 1 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:25|started process with pid 4508 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:25|restart process due to default exit code rule INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:25|restart internal RUNNING INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:25|stopping process with pid/timeout 4508 45000 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:26|process exit code: 1 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:31|started process with pid 14232 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:31|restart process due to default exit code rule INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:31|restart internal RUNNING INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:31|stopping process with pid/timeout 14232 45000 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:32|process exit code: 1 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:37|started process with pid 17972 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:37|restart process due to default exit code rule INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:37|restart internal RUNNING INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:37|stopping process with pid/timeout 17972 45000 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:38|process exit code: 1 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:43|started process with pid 14460 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:43|restart process due to default exit code rule INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:43|restart internal RUNNING INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:43|stopping process with pid/timeout 14460 45000 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:44|process exit code: 1 system.env 61 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:49|started process with pid 7148 INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:49|too many restarts INFO|wrapper|"WSO2 Carbon"|17-03-30 15:54:49|Shutting down Wrapper 。)