PHP依赖注入 - 魔术方法注入?

时间:2014-11-15 04:21:16

标签: dependency-injection phpunit magic-methods php-5.5

我正试着绕过DI。我是否正确地遵循DI模式的课程?

class Boo 
{
    public $title = 'Mr';
    public $name = 'John';
    protected $deps;

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

    public function methodBoo()
    {
        return 'Boo method '.$this->deps;
    }
}

class Foo 
{
    private $objects;

    public function __construct()
    {
    }

    // Set the inaccessible property magically.
    public function __set($name, $value)
    {
        $this->$name = $value;
    }

    // Set the inaccessible $class magically.
    public function __get($class)
    {
        if(isset($this->objects[$class]))
        {
            return $this->objects[$class];
        }
        return $this->objects[$class] = new $class($this->deps);
    }

    public function methodFoo()
    {
         return $this->Boo->methodBoo();
    }
}

$Foo = new Foo();
$Foo->deps = 'says hello';
var_dump($Foo->methodFoo());

结果,

string 'Boo method says hello' (length=21)

我不想在某些情况下使用构造注入因为并非Foo中的所有方法都依赖于相同的注入。例如,methodFoo()中的Foo仅依赖于Boo,而其他方法依赖于其他类/注入。

此外,我不想使用 setter injection ,因为我可能需要在Foo中编写大量的内容,例如

setBoo() {}
setToo() {}
setLoo() {}
... and so on...

所以我认为使用魔术方法__get__set可以避免我最终编写长列表。有了这个,我只有'注入'依赖Foo中的方法。

这是正确的做法吗?我之前没有进行任何单元测试。可以测试这个解决方案吗?

或者你有更好的解决方案?

1 个答案:

答案 0 :(得分:1)

如果可能,请不要使用魔术方法......

如果可能的话,不要使用魔术方法,因为它可能使你自己或其他任何人很难在以后回来并了解某些对象被注入的位置和方式(即使使用好的IDE)。这些__set和__get魔术方法不是您问题的长期解决方案,只会在长期内增加混乱。

如您所知,您可以使用&#39;构造函数&#39;注入用于设置属性并在对象实例化期间注入&#39; <&#39; 对象。

或者,如果您有依赖&#39; optional&#39; ,那么请使用setter / getter方法。这样你就会知道&#39;你的班级使用什么对象来执行它的功能。

如果您的班级需要说5个或更多依赖项(必需或可选),那么您的班级可能会尝试做很多事情。将其分解为需要较少依赖性的较小类,您会发现您的代码不仅变得更易读/可理解,而且更加模块化和可重用。 (关注点分离等)

关于使用魔术方法的类的测试,我确信它可以完成,但比没有使用魔术方法要痛苦得多。

Google&#39; Design Patterns&#39;。您找到并了解的设计模式将改善您加入的方式。或者&#39; wire&#39;你的课程一起。