Gre*_*han 5 php architecture zend-framework2
根据马可的Pivetta看法这个,这个老问题 和我的回答的另一个问题
我在询问自己在Zend Framework 2应用程序中使用我们的服务的更好方法.
实际上我们可以ServiceLocatorAwareInterface结合使用ServiceLocatorAwareTrait.事实上在ZF3中,服务定位器将被移除在控制器中它们可能也会删除此接口,或建议不使用它的人,这是有道理的.
我看到我们的服务如何构建的唯一方法是:
不要在服务中使用ServiceLocator,请使用DependancyInjection.
问题是 :
有些项目非常大,你要么:
您可能需要在服务中使用的一些示例:
也许对于其中的一些观点,它们可以通过我不知道的技巧来解决.
我的问题是:
在一个服务中拥有15个或更多Dependancies并放弃ServiceLocator,在控制器中,还是在服务中,这是一个好习惯吗?
从评论中编辑
为了说明我的观点,我粘贴了一个构造函数:
public function __construct(
ToolboxService $toolboxService,
EntityService $entityService,
UserService $userService,
ItemService $itemService,
CriteriaService $criteriaService,
Import $import,
Export $export,
PhpRenderer $renderer
) {
$this->toolboxService = $toolboxService;
$this->entityService = $entityService;
$this->userService = $userService;
$this->emOld = $this->toolboxService->getEmOld();
$this->emNew = $this->toolboxService->getEmNew();
$this->serviceLocator = $this->toolboxService->getServiceLocator();
$this->itemService = $itemService;
$this->criteriaService = $criteriaService;
$this->import = $import;
$this->export = $export;
$this->renderer = $renderer;
$this->formManager = $this->toolboxService->getFormManager();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,ToolboxService本身就是一个具有多个依赖项的对象.此服务位于我的Application文件夹中,几乎无处不在.我有2个实体经理(连接到2个数据库,但可能很快,我将需要第三个......)
您可以看到我通过依赖使用serviceLocator,因此该服务不会实现ServiceLocatorAwareInterface.如果我没有使用它,我可以用我的AbstractFactory调用
// Distribute somes orders depends on Clients
$distributionClass = $this->serviceLocator->get(ucfirst($param->type));
if ($distributionClass instanceof DistributeInterface) {
$distributionClass->distribute($orders, $key);
} else {
throw new \RuntimeException("invalid_type_provided", 1);
}
Run Code Online (Sandbox Code Playgroud)
假设您要注入ServiceLocator实例。无法保证ServiceLocator实际保存您的硬依赖项,从而破坏了 DI 模式。使用构造函数依赖注入时,您可以确保所需的所有服务确实可用。否则,服务的构建就会失败。
当使用 a 时,ServiceLocator您最终将进入一个实例化的服务类,其中硬依赖项可能通过ServiceLocator. 这意味着您必须编写所有类型的附加逻辑(检查依赖关系、抛出异常),以防在ServiceLocator您请求时无法从实例解析依赖关系。编写所有这些代码可能比注入 15 个依赖项要工作得多,而且最重要的是,整个服务中的逻辑将变得混乱。
此外,您仍然需要添加所有 setter 和 getter 方法,以便能够从您那里获取服务ServiceLocator并使您的服务可测试。
恕我直言,注入 15 个依赖项比注入实例代码更少,更容易维护ServiceLocator。