今天我更新了我的项目,我收到了这个警告:
不推荐使用:不推荐使用ServiceManagerAwareInterface 在3.0版中删除,以及ServiceManagerAwareInitializer。 请更新您的类X以删除实现,然后开始 通过工厂注入依赖项
我有一些实现Base
的主ServiceManagerAwareInterface
类和扩展这些基类的多个类。
为每个类创建额外的工厂类是一个好习惯吗?或者为每个模块使用 1 AbstractFactory 并在那里启动类更好?
使用AbstractFactory影响性能?
在许多类中注入单个(或2个)共享依赖项的最佳做法是什么?
更新: 即使我接受@ AlexP的答案,但我有一些关于提供依赖关系抛出构造函数的担忧。想象一下这个场景:我有一个带有几个动作的控制器,以免ActionA需要ServiceZ和ActionB需要ServiceY和ServiceX,而ServiceX也依赖于ServiceM和ServiceN。现在,每次我调用ActionA时我的控制器都启动了所有这些服务,但ActionA只需要1个服务,我的控制器加载了5个服务....这是一个好习惯吗?这是正确的做法吗?这会不会有糟糕的表现,因为在每次请求服务时都会启动我们在该请求期间根本不会使用的服务?
现在我允许每个服务/控制器满足自己的需求并在 时加载服务。
这样我就不必启动我不会使用的多个服务,而且我不需要知道服务依赖项来使用它们。我知道这不是最佳实践,但代码很干净,我更愿意牺牲“最佳实践”以获得更好的表现。
感谢任何人对此的意见。
答案 0 :(得分:4)
每个服务的工厂通常是理想的目标;但是在很多情况下,当你有类似的类具有相似的依赖关系,并且为每个类创建那么多的工厂将是不必要的并且难以维护。
抽象工厂通过匹配它可以按名称创建的每个服务来解决多个工厂问题,然后使用一些自定义配置返回一个新实例。
这引入了一些问题。
对$serviceManager->get()
或$serviceManager->has()
的调用将要求抽象工厂检查它是否可以使用其canCreateServiceWithName()
方法创建服务;对于多个抽象工厂,这可能会增加相当大的性能开销。
抽象工厂没有服务'别名'的概念;服务管理器提供的功能。实施要求您匹配服务的$requestedName
。如果您使用完整服务名称和别名调用服务,则会出现此问题。
抽象工厂与ZF2框架紧密结合。
该框架的路线图非常注重解决这些问题,ZF3仍然提供抽象工厂,但它也可以introduces some improvements in factory design to encourage reusability,你可以利用它。
请注意,工厂现在接受额外的必需参数
$requestedName
; v2已经传递了这个参数,但是它没有在接口本身中指定。 由于工厂现在可以接收服务名称,因此可以将它们重新用于多种服务,主要是替换版本3中的抽象工厂。
因此,我们已经可以将标准工厂多次次用于类似服务(在ZF2中)。
关于如何使用一个工厂创建类似服务的一个非常简单的示例。
'service_manager' => [
'factories' => [
'My\Service\Foo' => 'My\Factory\SharedFactory',
'My\Service\Bar' => 'My\Factory\SharedFactory',
'My\Service\Baz' => 'My\Factory\SharedFactory',
],
],
namespace My\Factory;
class SharedFactory
{
public function __invoke($serviceLocator, $name, $requestedName)
{
if (! class_exists($requestedName)) {
throw new ServiceNotCreatedException("$requestedName could not be found!");
}
return new $requestedName(
$serviceLocator->get('SomeDependacy1'),
$serviceLocator->get('SomeDependacy2')
);
}
}
您可以使用$requestedName
参数轻松扩展此加载自定义服务配置,以增加更大的灵活性。