这里有很多关于此的讨论,但似乎没有人真正回答这个问题。
我目前正在考虑使用Symfony 2 service container。我看的越多,看起来我就可以用服务工厂做同样的事了。请考虑以下示例:
services.yml
services:
my_mailer:
class: Acme\Mailer
arguments: [sendmail]
newsletter_manager:
class: Acme\Newsletter\NewsletterManager
arguments: [@my_mailer]
现在要获得一名时事通讯经理,我会这样做:
// this has been configured with the above yml file
$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->get("newsletter_manager");
但是,请考虑以下工厂样式代码:
class ServiceContainer
{
public function getMyMailer()
{
return new Acme\Mailer("sendmail");
}
public function getNewsletterManager()
{
return new Acme\Newsletter\NewsletterManager($this->getMyMailer());
}
}
然后使用它:
$serviceContainer = new ServiceContainer();
$newsletterManager = $serviceContainer->getNewsletterManager();
这里有什么我想念的吗?因为如果工厂可以为我做所有这些,我真的没有看到使用DI容器的优势。
我听说使用工厂导致你的代码“依赖于工厂”。我要么不明白这个论点,要么反对工厂的人是混淆的。只有顶级类(组合根)才能引用工厂,就像它是唯一一个引用DI容器一样。
答案 0 :(得分:2)
我有什么东西在这里失踪吗?因为我没有真正看到 使用DI容器的优势,如果工厂可以完成所有这些 我
是的 - 您正在使用Service Locator (anti-)pattern使用您的DI容器,而不是将您的依赖项注入您的类。你的班级根本不应该参考你的DI容器。
相反,应该只有一个聚合根,您可以在其中创建容器并解析所有依赖关系。一旦解决了顶级类实例,然后使用Hollywood Principle使用IoC容器解析所有依赖项(以及依赖项的依赖项等) - 当创建类实例时,将传递其所有依赖项在,实例从不要求依赖本身。