Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection Laravel 4:立面与DI(何时使用)_Dependency Injection_Laravel_Laravel 4 - Fatal编程技术网

Dependency injection Laravel 4:立面与DI(何时使用)

Dependency injection Laravel 4:立面与DI(何时使用),dependency-injection,laravel,laravel-4,Dependency Injection,Laravel,Laravel 4,我的理解是,facade被用作依赖注入的替代品。如果我弄错了,请改正。不清楚的是何时应该使用其中一种 每种方法的优点/缺点是什么?我应该如何确定何时使用其中一种 最后,为什么不同时使用两者呢?我可以创建引用接口的外观。《哨兵2》似乎是这样写的。有最佳实践吗?正面 不是依赖注入的替代方案 Laravel Facade是服务定位器模式的一个实现,创建了一种干净漂亮的访问对象的方式: MyClass::doSomething(); 这是静态方法的PHP语法,但Laravel改变了游戏,使它们在幕后成

我的理解是,facade被用作依赖注入的替代品。如果我弄错了,请改正。不清楚的是何时应该使用其中一种

每种方法的优点/缺点是什么?我应该如何确定何时使用其中一种


最后,为什么不同时使用两者呢?我可以创建引用接口的外观。《哨兵2》似乎是这样写的。有最佳实践吗?

正面

不是依赖注入的替代方案

Laravel Facade是服务定位器模式的一个实现,创建了一种干净漂亮的访问对象的方式:

MyClass::doSomething();
这是静态方法的PHP语法,但Laravel改变了游戏,使它们在幕后成为非静态的,为您提供了一种漂亮、有趣且可测试的应用程序编写方式

依赖注入

依赖注入基本上是一种将参数传递给构造函数和方法,同时自动恢复它们的方法

class MyClass {

    private $property;

    public function __construct(MyOtherClass $property)
    {
        /// Here you can use the magic of Dependency Injection

        $this->property = $property

        /// $property already is an object of MyOtherClass
    }

}
更好的构造方法是在依赖注入构造函数上使用接口:

class MyClass {

    private $property;

    public function __construct(MyInterface $property)
    {
        /// Here you can use the magic of Dependency Injection

        $this->property = $property

        /// $property will receive an object of a concrete class that implements MyInterface
        /// This class should be defined in Laravel elsewhere, but this is a way of also make 
        /// your application easy to maintain, because you can swap implementations of your interfaces
        /// easily
    }

}
但请注意,在Laravel中,可以以相同的方式注入类和接口。要注入接口,您只需告诉它以下哪种方式:

App::bind('MyInterface', 'MyOtherClass');
这将告诉Laravel,每当您的一个方法需要MyInterface实例时,它都应该给它一个MyOtherClass实例

这里发生的是,这个构造函数有一个“依赖项”:
MyOtherClass
,它将由Laravel使用自动注入。因此,当您创建
MyClass
的实例时,Laravel会自动创建
MyOtherClass
的实例,并将其放入变量
$class

依赖注入只是一个奇怪的术语,开发人员创建依赖注入只是为了做一些简单的事情,比如“自动生成参数”

何时使用其中一种?

正如您所看到的,它们是完全不同的东西,因此您永远不需要在它们之间做出决定,但您必须决定在应用程序的不同部分使用其中一个或另一个

使用Facades简化编写代码的方式。例如:为应用程序模块创建包是一种很好的做法,因此,为这些包创建外观也是一种使它们看起来像Laravel公共类并使用静态语法访问它们的方法


每当您的类需要使用来自另一个类的数据或处理时,请使用依赖项注入。它将使您的代码可测试,因为您将能够“注入”这些依赖项的模拟到您的类中,并且您还将实践这一原则(请看一看)。正如前面提到的,Facades旨在简化潜在的复杂接口。

外观仍然可以测试 Laravel的实现更进一步,允许您定义Facade“指向”的基类

这使开发人员能够通过使用模拟对象切换基类来“模拟”外观

从这个意义上讲,您可以使用它们并且仍然拥有可测试的代码。这就是PHP社区中存在的一些混乱之处

DI经常被引用为使代码可测试——它们使模拟类依赖关系变得容易。(旁注:接口和DI存在其他重要原因!)

另一方面,Facades经常被引用为使测试更加困难,因为您不能“简单地将模拟对象注入”正在测试的任何代码中。然而,如前所述,您实际上可以“模仿”它们

立面vs DI 这就是人们对Facade是否是DI的替代品感到困惑的地方

从某种意义上说,它们都为类添加了依赖项—您可以使用DI添加依赖项,也可以直接使用FacadeName::method($param)。(希望您没有直接在另一个:D中实例化任何类)


这并没有使Facades成为DI的替代品,但是,在Laravel中,确实产生了这样一种情况,即您可以决定使用DI或Facade两种方式之一来添加类依赖项。(当然,您可以使用其他方式。这“2种方式”只是最常用的“可测试方式”)。

Laravel的Facades是服务定位器模式的实现,而不是Facade模式

在我看来,您应该避免在您的域中使用服务定位器,选择只在您的服务和web传输层中使用它


我认为,就laravel Facades而言,它可以帮助您保持代码的简单性和可测试性,因为您可以模拟Facades,但是如果您使用Facades,则可能更难判断控制器依赖性,因为它们可能在您的代码中无处不在

使用依赖项注入,您需要编写更多的代码,因为您需要创建接口和服务来处理依赖项。但是,由于控制器构造函数中明确提到了这些接口和服务,因此以后控制器所依赖的内容会更加清楚


我想这是一个决定你更喜欢使用哪种方法的问题。在你的例子中,
MyOtherClass
的类型暗示是否有点违背DI的观点?@WesleyMurch Nope!例如,如果没有DI,您可以将MyOtherClass的构造函数参数作为MyClass构造函数参数,然后在MyClass构造函数中创建MyOtherClass的实例。现在MyClass对MyOtherClass有一个“隐藏的依赖项”。DI改变了这一点,因此MyOtherClass在外部创建并注入,MyClass的构造函数签名声明了依赖关系——不再隐藏。类型提示接口意味着您可以编写MyClass构造函数,前提是您正在使用MyOtherClass,就像您在那里创建实例一样。我真的看不出区别。和depende一样