0

我正试图了解 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()in仅Foo依赖于Boo,而其他方法依赖于其他类/注入。

另外,我也不想使用setter 注入,因为我可能必须在其中写很多Foo,比如

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

所以我想使用魔术方法__get__set可以避免我最终写出一长串的清单。有了这个,我Foo.

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

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

4

1 回答 1

1

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

如果可能,请不要使用魔法方法,因为这会使您或其他任何人在以后回来并了解某些对象的注入位置和方式变得非常困难(即使使用好的 IDE 也是如此)。这些 __set 和 __get 魔术方法不是解决问题的长期方案,从长远来看只会增加混乱。

如您所知,您可以使用“构造函数”注入来设置属性并在对象实例化期间注入“必需”的对象。

或者,如果您有“可选”的依赖项,则使用 setter / getter 方法。这样你就“知道”你的类使用什么对象来执行它的功能。

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

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

谷歌“设计模式”。您对设计模式的发现和学习将改善您将课程“加入”或“连接”在一起的方式。

于 2015-04-20T15:36:00.907 回答