Symfony2保持DRY的最佳实践

时间:2015-01-02 11:56:17

标签: symfony doctrine-orm coding-style dry

我是Symfony2的新手。我必须为我的新工作学习它(从星期一开始)。在此之前,我使用了很多CodeIgniter ...所以这个改变了一点。

阅读了大量的文档,tuts,最佳实践...创建我自己的内部网进行测试(客户有网站,网站有访问,访问有网站,网站有类别,访问有访问类别)我还有一些问题。< / p>

第一个问题:

当你有一个带前端和后端的网站时,你总是会有一些重复的动作,例如: - 创建新实体 - 阅读实体 - 更新实体 - 删除实体 ...

在CI中,我创建了一个BaseController和一个BaseModel,并且通过一些扩展,我很好。

对于Symfony 2,这种做法仍然可以,或者Symfony有另一种处理方法吗?

像AppBundle \ Controller \ PageController一样扩展的AppBundle \ Controller \ AdminController(和FrontController)延伸的AppBundle \ Controller \ BaseController?

因为实际上,每次在每个控制器中我都有相同的代码。当我编辑实体时(例如),它是相同的过程:通过id加载实体,如果没有实体则抛出异常,创建和保存表单,handleRequest帖子并使表单有效,重新显示或显示视图......但是...我总是剪切/粘贴相同的代码...非常好的T__T

所以我正在寻找处理这个问题的最佳方法

**第二个问题:**

使用DoctrineManager的最佳和最佳方式是什么?

每次我的行动都需要打电话吗? $em = $this->get...或者,我可以创建MyEntityManager之类的东西来调用EntityManager和我的实体的存储库吗?

实际上,这就是我的工作:

我使用loadAndFlush

创建一个抽象的AppBundle \ Manager \ BaseManager
<?php

namespace AppBundle\Manager;

abstract class BaseManager
{
    protected function persistAndFlush($entity)
    {
        $this->em->persist($entity);
        $this->em->flush();
    }

}

然后,对于每个实体,我创建了自己的经理:

<?php

namespace AppBundle\Manager;

use Doctrine\ORM\EntityManager;
use AppBundle\Manager\BaseManager;
use AppBundle\Entity\Customer;

class CustomerManager extends BaseManager
{
    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * @param EntityManager $em
     */
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    /**
     * @param $customerId
     * @return null|object
     */
    public function loadCustomer($customerId)
    {
        return $this->getRepository()
            ->findOneBy(array('id' => $customerId));
    }

    /**
     * @param Customer $customer
     */
    public function saveCustomer(Customer $customer)
    {
        $this->persistAndFlush($customer);
    }

    /**
     * @return \Doctrine\ORM\EntityRepository
     */
    public function getRepository()
    {
        return $this->em->getRepository('AppBundle:Customer');
    }

}

然后,我将此经理定义为服务:

parameters:
    app.customer_manager.class: AppBundle\Manager\CustomerManager

services:
    app.customer_manager:
        class: %app.customer_manager.class%
        arguments: [@doctrine.orm.entity_manager]

然后我在我的Controller中使用该服务:

/**
 * @Route("/edit/{customerId}", name="customer_edit")
 * @Security("has_role('ROLE_ADMIN')")
 */
public function editAction($customerId, Request $request)
{
    if (!$customer = $this->get('app.customer_manager')->loadCustomer($customerId)) {
        throw new NotFoundHttpException($this->get('translator')->trans('This customer does not exist.'));
    }

    $form = $this->get('form.factory')->create(new CustomerType(), $customer);

    if($form->handleRequest($request)->isValid()) {

        $this->get('app.customer_manager')->saveCustomer($customer);

        $request->getSession()->getFlashBag()->add('notice', 'Client bien enregistré.');

        return $this->redirect(
            $this->generateUrl(
                'customer_show', array(
                    'customerId' => $customer->getId()
                )
            )
        );
    }

    return $this->render('default/customer/add.html.twig', array(
        'form'      => $form->createView(),
        'customer'  => $customer
    ));

}

这是一个好习惯,是不是太复杂了?在symfony中有没有更好的其他处理方式?

1 个答案:

答案 0 :(得分:0)

对于第一个问题,Symfony2提供了CRUD Generator,请查看this

对于第二个,您应该使用框架提供的存储库模式,有关此结帐的更多信息,请访问以下链接:

  1. http://msdn.microsoft.com/en-us/library/ff649690.aspx
  2. http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes