Php 使用依赖项注入在类中实例化对象的最佳方法是什么?

Php 使用依赖项注入在类中实例化对象的最佳方法是什么?,php,dependency-injection,dependencies,service-locator,Php,Dependency Injection,Dependencies,Service Locator,我正在潜入依赖注入的世界,我遇到了一个问题。情况如下: 我有一个ImageGenerator,可以为特定情况生成图像。在这个ImageGeneratorI“构造函数”中注入几个字符串(文件路径)和一个Translator类。现在,我使用一个依赖项容器来实现这一点,该容器实例化了ImageGenerator和Translator。到目前为止还不错 在ImageGenerator内部,我现在在几个地方硬编码了新的Imagick(…)。我也在寻找一种注入这些依赖项的方法,以便将来可以切换到不同的映像类

我正在潜入依赖注入的世界,我遇到了一个问题。情况如下:

我有一个
ImageGenerator
,可以为特定情况生成图像。在这个
ImageGenerator
I“构造函数”中注入几个字符串(文件路径)和一个
Translator
类。现在,我使用一个依赖项容器来实现这一点,该容器实例化了
ImageGenerator
Translator
。到目前为止还不错

在ImageGenerator内部,我现在在几个地方硬编码了
新的Imagick(…)
。我也在寻找一种注入这些依赖项的方法,以便将来可以切换到不同的映像类。为此,我使用两个类创建了一个抽象:
ImagickImage
GDImage
,这两个类都实现了
ImageInterface
中定义的一组方法

问题是,如何在
ImageGenerator
中获取正确的
ImageInterface
实例?我提出了一些选择,但都不正确

谁能启发我


选项1,使用ImageFactory类 我可以向
ImageGenerator
中注入一个实现
ImageFactory
接口的对象。
ImageFactory
接口有一个方法
instantiate($filePath)
,该方法返回
ImageInterface
的新实例。问题是,我最终得到了很多这样的类和接口:

ImageInterface
ImagickImage
GDImage
ImageFactoryInterface
ImagickImageFactory
GDImageFactory

选项2,在ImageInterface中使用静态工厂方法 由于工厂的
instantiate
方法只有一行,我想我可以向
ImageInterface
类添加一个静态
instantiate
方法。然后我可以将
ImageInterface
的一个实例注入到ImageGenerator中,它将作为工厂来创建新实例

选项3,插入图像的类名 我还可以将image类的类名(无论是
ImagickImage
还是
GDImage
)注入
ImageGenerator
类。然后我就可以基于该类名创建新实例

选项4

我选择选项1,因为除非您决定离开Imagick,否则您不需要编写
GDImage
GDImageFactory
。所以你不会添加很多类,只有
ImageFactory
ImagickImageFactory
。好的,我只需要在移动到GD后使用工厂。然而,创建这样的接口和类感觉有点过火:
返回新的ImagickImage($filePath)。我现在倾向于选择3。它很简单,几乎没有开销。缺点是没有那么明显,没有界面来表明意图。我同意@MatthieuNapoli。与将实例化逻辑硬编码到
ImageGenerator
中相比,轻微的类膨胀是一个更好的选择。此外,您的DI框架可能已经有了解决方案。例如,如果您使用的是Guice,您可以通过辅助注入注入一个
提供者
,甚至一个自动生成的工厂实现。我现在去工厂了。然而,这意味着对于每个可实例化类,我至少还需要2个文件(接口+实现)。