【问题标题】:Best practice Symfony2 entity management最佳实践 Symfony2 实体管理
【发布时间】:2015-09-02 09:35:47
【问题描述】:

Symfony2中有很多管理实体的方法,但我不知道哪个更好

解决方案 1:在控制器中

public function myAction()
{
    $myEntity = new MyEntity();
    $form = $this->createForm($myEntityType, $myEntity);

    ...

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager()
        $em->persist($myEntity);
        $em->flush()
    }

    ...
}

解决方案 2:使用自定义 entityManager

public function myAction()
{
    $myEntityManager = $this->get('manager.my_entity');
    $myEntity = $myEntityManager->create();
    $form = $this->createForm($myEntityType, $myEntity);

    ...

    if ($form->isValid()) {
        $myEntityManager->update($myEntity);
    }

    ...
}

解决方案 3:使用工厂

public function myAction()
{
    $myEntityFactory = $this->get('factory.my_entity');
    $myEntity = $myEntityFactory->create();
    $form = $this->createForm($myEntityType, $myEntity);

    ...

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager()
        $em->persist($myEntity);
        $em->flush()
    }

    ...
}

我更喜欢解决方案 2,但人们告诉我这不是单一责任模式,因为你有一个工厂和一个更新它的方法。解决方案可能是在管理器中使用工厂,但这会带来一些复杂性。

【问题讨论】:

  • 第一种方式肯定不好。那是因为在控制器中创建对象(new 运算符硬编码)会降低可测试性。
  • 恐怕这将主要基于意见。 IMO 以上解决方案均不正确。控制器应该只将数据传递给域模型并根据结果返回响应。没有实体管理器、表单处理、对象实例化之类的东西。第三种解决方案可能更可取,但前提是它被移动到正确的域模型对象并且没有留在控制器中。

标签: symfony


【解决方案1】:

仅取决于用例,IMO。没有单一的“最佳方式”。

问题是:在您的应用程序中,您实际上对这个实体做了什么?您需要访问多少次相同的方法?

如果只在一个地方,那么在控制器之外创建服务或任何东西可能是完全没有必要的。

工厂设计模式有它自己的用法,所以它是一个单独的问题来分析(不管实体)。

不过,当您只需要创建一个实体时,我会在大多数用例中使用第一个选项:

$myEntity = new MyEntity();

为什么?因为代码不会隐藏任何东西。来吧,MyEntity 只是一个普通对象,它不需要任何服务或管理器或(在大多数情况下)工厂。其他两个似乎是一个不好的做法,因为它们隐藏了那里真正发生的事情(除非需要工厂)。

【讨论】:

    【解决方案2】:

    控制器

    public function myAction()
    {
        $myEntity = $this->get('entity_repository')->getBySomething();
        $form = $this->createForm($myEntityType, $myEntity);
    
        ...
    
        if ($form->isValid()) {
            $this->get('entity_persister')->updateEntity($myEntity);
        }
    
        ...
    }
    

    您的存储库唯一负责为您提供模型对象。 域服务 'entity_persister' 负责将给定的数据持久化到模型中

    请注意,此解决方案不是最简洁的方法,因为您的表单直接映射到表示数据库表的对象。如果你想要一个更简洁的架构来保持模型对象和表单映射的对象不同,我会推荐。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      相关资源
      最近更新 更多