php - php中这两种构造函数注入(inject)有什么区别?

标签 php laravel dependency-injection type-hinting

我想了解 PHP 中的依赖注入(inject),我发现在 Laravel 中有两种方法可以做到这一点。

那么假设我有一个像这样的 Foo 类:

class Foo{

}

现在我有一个名为 Bar 的类,它依赖于 Foo 所以我可以这样做:

class Bar{
    protected $foo;
    public function __construct()
    {
        $this->foo = new Foo();
    }
}

但是在 Laravel 中,我遇到了像类型提示和反射这样的术语,它们允许我这样做:

class Bar{
    protected $foo;
    public function __construct(Foo $foo)
    {
        $this->foo = $foo;
    }
}

我想了解的是这两者之间的区别。它们完全相同吗?有什么特别的理由让我更喜欢另一个吗?

PS:我是新手,我不确定我是否正确使用了问题中的行话。

最佳答案

它主要归结为代码的耦合

class Foo {
    public function __construct() {
        new Bar;
    }
}

这将一个非常具体的 Bar 耦合到这个特定的 Foo。如果不重写这段代码,就无法改变 哪个 Bar 被实例化。这也意味着 Foo 需要了解 Bar 的依赖关系。也许今天 Bar 可以用 new Bar 实例化。但也许明天您正在重构 Bar 并且现在必须使用 new Bar($database) 实例化它。现在您还需要重写 Foo 以适应它。

这就是依赖注入(inject)的用武之地(上面的不是依赖注入(inject),你没有注入(inject)任何东西):

class Foo {
    public function __construct(Bar $bar) { }
}

这个 Foo 只是声明它在实例化时需要一个具有 Bar 特征的对象。但是 Foo 不需要知道 Bar 是如何产生的,它的依赖项是什么或者它到底做了什么。它对 Bar 的唯一期望是定义的 public 接口(interface),关于它的任何其他内容都是无关紧要的。事实上,为了获得更大的灵 active ,您可能希望在此处使用 interface 而不是具体的类依赖项。

依赖注入(inject)允许您将类的具体细节与其他代码分离。它允许您拥有一个实例化类的中心位置,这是您需要了解和考虑有关您正在实例化的类的具体细节的地方。例如,这可以是一个依赖注入(inject)容器。您不希望到处散布类实例化逻辑,因为如上所述,该逻辑可能会发生变化,然后您需要到处重写代码。

require_once 'Foo.php';
require_once 'Bar.php';

$foo = new Foo(new Bar);

上面的代码是决定将哪个 Bar 注入(inject)Foo 的地方。这也是需要担心 Bar 依赖的地方。请注意,依赖项加载和实例化是这段代码唯一要做的事情。根据需要仅更改这段代码是微不足道的,无需触及可能充满复杂业务逻辑的 FooBar

依赖注入(inject)代码还允许您将应用程序分开并灵活地组合在一起。例如用于测试目的。或者只是在不同的上下文中灵活地重用不同的组件。

另见 How Not To Kill Your Testability Using Statics .

关于php - php中这两种构造函数注入(inject)有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32837343/

相关文章:

dependency-injection - Java EE 7 : How-to inject an EJB into a WebSocket ServerEndpoint?

javascript - 使用 POST 数据的数组键或数组值的 RESTful api

c# - Unity 3,RegisterTypes方法在哪里?

php - 通过 PHP 或命令行将 SVG 转换为 DXF 或 DWG?

JavaScript 如何从脚本文件中获取 get var

php - 此代码对 SQL 注入(inject)安全吗

php - 在 Laravel 上合并具有值(value)的属性

php - Laravel 数组键存在于 get 方法中

laravel - 在 Laravel 中过滤权限时的最佳性能方法

c# - 使用 Controller 方法注入(inject) Dotnet 核心方法