Php 避免构造函数服务Symfony中的长参数列表
我一直在使用Symfony开发我的web应用程序,但我一直遇到一个问题。由于我希望能够正确地对我的服务进行单元测试,因此我的服务的构造函数中总是会有太多的混乱 理论用例 假设我需要一个服务,它允许我处理XML文件并将其内容保存到数据库中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
<?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']]