繁体   English   中英

Symfony-使用服务工厂或服务配置程序会更好吗?

[英]Symfony - Is it better to use a service factory or a service configurator?

在Symfony中,似乎有两种方法可以动态实例化服务:

两种方法似乎都是最新的。 检查问题和变更日志并没有给我更多有关哪种方法最常见或哪种方法被视为最佳实践的信息。

因此,我应该在服务配置器上使用服务工厂,还是在工厂使用服务配置器? 为什么以及最近的是哪个?

非常感谢!

基本上,它们是不一样的:使用工厂创建服务,使用配置程序在创建服务后对其进行配置。

当您需要实例化服务(并可能注入其他服务或参数)时,请使用标准服务配置文件(即: services.yml )。

需要控制服务实例化时,请使用工厂。

创建服务后需要配置服务时,并且要将服务定义与服务配置分开时,请使用服务配置器。

在某些特殊情况下,最好通过服务配置器使用服务工厂:

1)为较旧的PHP类创建服务定义,因为过去,创建逻辑通常隐藏在静态工厂类中,例如Doctrine_Core :: getTable()

public static function getTable($componentName)
{
    return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);
}

https://github.com/doctrine/doctrine1/blob/master/lib/Doctrine/Core.php

2)使用工厂服务和方法检索服务的一个特别好的例子是Doctrine存储库。 当需要时,通常将实体管理器作为构造函数参数注入,然后检索特定的存储库:

use Doctrine\ORM\EntityManager;

class SomeClass
{
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function doSomething()
    {
        $repository = $this->entityManager->getRepository('User');
    }
}

但是,使用工厂服务和方法,您可以直接注入正确的存储库本身:

class SomeClass
{
    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }
}

...

<service id="some_service" class="SomeClass">
    <argument type="user_repository" />
</service>

...

<service id="user_repository" class="UserRepository"
   factory-service="entity_manager" factory-method="getRepository">
   <argument>User</argument>
</service>

通过查看SomeClass的构造函数参数,可以很明显地看出它需要一个User信息库,它比之前的SomeClass需要EntityManager的示例更加具体和可通信。 除了使类本身更加整洁外,在编写此类的单元测试时,还将使为存储库创建替代对象变得更加容易。 无需为实体管理器和存储库创建模拟,只需为存储库本身创建一个模拟即可。

使用服务工厂的缺点是(根据Matthias的说法):

我反对使用静态工厂方法的工厂类,因为静态代码是全局代码,执行该代码可能会产生无法隔离的副作用(例如,在测试场景中)。 此外,此类静态工厂方法的任何依赖关系都必须按照定义本身就是静态本身,这对于隔离也确实很不利,并且会阻止您用自己的代码替换(部分)创建逻辑。 工厂对象(或工厂服务)要好一些。 但是,对它们的需求很可能指向某种设计问题。 服务不需要工厂,因为它将仅以预定(确定性)的方式创建一次,并且此后可以被其他任何对象完美地重用。 关于服务的唯一动态内容应该是属于其公共接口的方法的参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM