给出一个课程:
class Container
{
public function getServiceX()
{
create and return it
}
public function setServiceX ($obj)
{
}
}
这存储了一个对象的实例。你可以把它当作工厂。在行动:
public function addTitle()
{
Container::getServiceX()->doIt();
}
他们说它不好,因为它的“全球化”。但是对象可以改变,因此它满足DI - 但是伤害了LoD。
如果那不好,有什么好的解决方案?如何确保一个类到达serviceX?
答案 0 :(得分:4)
基本上,这是服务定位器或服务工厂。您甚至可以将其称为依赖注入容器。这本身就很好。事实上这很棒。它的问题是你静静地称它!您应该将依赖注入容器注入您的类:
class Foo {
protected $container;
public function __construct(Container $container) {
$this->container = $container;
}
public function addTitle() {
$this->container->getServiceX()->doIt();
}
}
在那里,现在你完全依赖注入和解耦。
通过静态耦合调用,您仍然可以首先进入您尝试避免使用依赖注入容器的情况。如果您需要为服务X注入一个类而使用稍微不同配置的服务X实例注入第二个类,但是您静态调用只能容纳服务X的一个副本的同一容器,该怎么办?您通过将静态调用与容器分离并允许注入不同配置的容器来解决此问题。
答案 1 :(得分:1)
使用全局包含会使测试代码变得更加困难。你也没有太多的对象状态控制。这是针对SOLID的。
依赖注入是一种更好的方法。
点击此链接What's the difference between the Dependency Injection and Service Locator patterns?
使用依赖注入时,您可以轻松地模拟对象并使其易于测试。您不会静态传递或创建它们,但是例如通过服务的构造函数传递它们。
您还可以查看Symfony2开发人员如何做到这一点:http://symfony.com/doc/current/components/dependency_injection/index.html