Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 避免构造函数服务Symfony中的长参数列表_Php_Symfony_Unit Testing_Dependency Injection - Fatal编程技术网

Php 避免构造函数服务Symfony中的长参数列表

Php 避免构造函数服务Symfony中的长参数列表,php,symfony,unit-testing,dependency-injection,Php,Symfony,Unit Testing,Dependency Injection,我一直在使用Symfony开发我的web应用程序,但我一直遇到一个问题。由于我希望能够正确地对我的服务进行单元测试,因此我的服务的构造函数中总是会有太多的混乱 理论用例 假设我需要一个服务,它允许我处理XML文件并将其内容保存到数据库中 <?xml version="1.0" encoding="UTF-8" ?> <users> <user> <id>1234</id> <username

我一直在使用Symfony开发我的web应用程序,但我一直遇到一个问题。由于我希望能够正确地对我的服务进行单元测试,因此我的服务的构造函数中总是会有太多的混乱

理论用例 假设我需要一个服务,它允许我处理XML文件并将其内容保存到数据库中

<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user>
        <id>1234</id>
        <username>Example User</username>
        <email>user@example.com</email>
        <usergroup>
            <id>567</id>
            <name>Example User Group</name>
        </usergroup>
        <permissions>
            <item>ALLOWED_TO_CREATE</item>
            <item>ALLOWED_TO_UPDATE</item>
            <item>ALLOWED_TO_DELETE</item>
            <item>ALLOWED_TO_view</item>
        </permissions>
    </user>
</users>
专业人士

  • 可以说更容易阅读
缺点

  • 更多代码
  • 服务不再是强制性的,可能需要可选验证
问题: 在可读性和单元测试能力方面,哪些解决方案可以使我的服务中的参数列表更易于维护


拥有一长串参数甚至被认为是不好的做法吗?

在构造函数中拥有许多参数是一种错误的做法。这种代码气味通常表示类承担了太多的责任,这意味着它违反了(SRP)。违反SRP会导致维护问题,因此您应该密切关注这些问题

尽管重构到属性注入可能会减少构造函数参数的数量,从而减少构造函数中的混乱程度,但它并不能解决底层问题,即此类变得太复杂。因此,属性注入不是构造函数过度注入的解决方案

这种代码气味的解决方案是降低手头类的复杂性。有很多方法可以做到这一点,但一种非常常见的方法是:

门面服务[与]密切相关,但主要区别在于参数对象仅将参数移动到公共根,而门面服务隐藏了新抽象背后的聚合行为。虽然Facade服务可能是通过纯粹的机械重构开始其生命的,但事实往往证明,提取的行为本身就代表了一个领域概念

赞成的意见:
  • 降低了类的复杂性,从而解决了底层问题
  • 防止依赖条令服务(这是的应用程序)
  • 介绍领域语言的新概念和改进
  • 防止属性注入(因为属性注入导致)
欺骗:
  • Facade服务可能不是正确的重构。替代方案是和

这些都是我们和我在书中讨论的话题,例如,专门讨论了从构造函数到Façade服务或域事件的重构,同时深入探讨了decorator的使用。

例如,考虑将UserRespository、UserGroupRepository和PermissionRepository组合到某种UserFinder服务中。对于您正在注入的所有单个服务,我认为如果您认为您正在进行适当的单元测试,那么您可能是在愚弄自己。其中一个技巧是将persist/flush添加到存储库中,这通常避免了直接与实体管理器打交道的需要。现在,您的脑海中有一个形象,用户用户组和权限都是单独的对象,但实际上,在这个特定的设计上下文中,您真正拥有的只是一个更复杂的用户对象。
services:
  AppBundle\Service\MyImportService:
    calls:
      - [setUserRepository, ['@app.user_repository']]