2015-09-07 30 views
2

给定的类:Php,为什么“全球容器”不好,以及如何避免它?

class Container 
{ 
    public function getServiceX() 
    { 
     create and return it 
    } 

    public function setServiceX ($obj) 
    { 
    } 
} 

此存储的对象的实例。你可以把它当作一个工厂。在行动:

public function addTitle() 
{ 
    Container::getServiceX()->doIt(); 
} 

他们说它的坏,因为它的“全球”。但物体可以改变,所以它可以满足DI - 但伤害LoD。 如果那不好,有什么好的解决方案?如何确保一个班级到达serviceX?

+3

全局通常被视为坏,因为人们不知道如何正确地对待他们。但是,对于某些使用情况,将类用作单例实例可能完全有效。我的问题是更多......他们是谁? – Tschallacka

回答

3

本质上这是一个服务定位器或服务工厂。你甚至可以称之为依赖注入容器。这本身就非常好。事实上它很棒。问题在于你静态调用它!有

class Foo { 

    protected $container; 

    public function __construct(Container $container) { 
     $this->container = $container; 
    } 

    public function addTitle() { 
     $this->container->getServiceX()->doIt(); 
    } 

} 

,现在你完全依赖注入和去耦:你应该注入你的依赖注入容器到类。

通过静态耦合调用,您仍然可以进入首次尝试避免使用依赖注入容器的情况。如果你需要注入一个带有服务X的类和另一个带有稍微不同配置的服务X实例的类,但是你正在静态调用同一个只能容纳一个服务X的容器?您正在通过将静态调用与您的容器分离并允许注入不同配置的容器来解决此问题。

+1

@John您可能对此感兴趣:[如何不使用静态技术来杀死您的测试性](http://kunststube.net/static/) – deceze

+0

当然,但为什么甚至要实例化这个Container?不需要它的一个实例。 –

+2

因为这正是OOP的全部内容。因为可能*今天*你不能同时看到'容器'有两个不同的实例*。但是明天你可能会发现自己处于我在答案中描述的状态,并希望你可以有两个独立的容器实例。 – deceze

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

+0

,但您也可以为Container设置对象,而不仅仅是对它们进行硬编码。 –

相关问题