首页 > 编程知识 正文

依赖注入是什么,php依赖注入容器库

时间:2023-05-04 18:04:47 阅读:116433 作者:562

个人资料

PHP从属注入简称DI。 依赖注入是一种更容易维护、更容易测试并要求更模块化代码的解决方案。

什么是依赖

每个项目都有依赖关系(外部输入),项目越复杂,就需要更多的依赖关系。 在当今的网络APP应用程序中,最常见的依赖关系是数据库,如果数据库关闭,整个程序可能会有停止的风险。 这是因为代码依赖数据库服务器……这就足够了。 因为数据库服务器可能会崩溃,而且将其销毁是荒谬的。 依赖有自己的缺陷,但代码中仍然存在,以便于程序开发人员的工作。

不依赖注入的弊端

在许多依赖关系中,问题是代码如何处理以及如何与它们交互。 也就是说,问题不在于依赖,而在于代码本身。 如果未使用依赖注入,请单击class Book {

公共函数_ _ construct (

{

$ registry=registry singleton :3360 getinstance (;

$ this-_ database connection=$ registry-database connection;

//or

全局$数据库连接;

$ this-_ database connection=$ database connection;

}

}

创建对象book后,它将完全连接到数据库。 这不是坏事。 book需要与数据库进行交互以获取数据。 问题是book获取其访问权限的方法。 代码需要外部变量$databaseConnect才能使book与数据库交互。 更糟的是,需要包含数据库连接记录的singleton类(registry )对象。 如果它们不存在,book就无法运行,这些代码不是模块化的。

这是一个关于book如何访问数据库的问题。 这就是IoC出现的原因。

依赖注入的解决方案IoC

在好莱坞,穷途末路的演员不会打电话给Martin Scoresese,要求他在下一部电影中扮演角色。 绝对没有那样的事。 实际情况正好相反。 Martin Scorese会给这个有困难的演员打电话,邀请他在下一部电影中扮演重要角色。 对象是挣扎的演员,不会去捡腼腆的啤酒。 导演需要告诉他们要做什么。 对象不会选择系统给它接触的外界,相反外界系统会被赋予对象。 请记住,这是inversionofcontrol (IOC )控件的反转。

是开发者告诉他的对象如何与外界的依赖打交道。 class Book {

公共函数_ _ construct

publicfunctionsetdatabaseconnection ($ database connection ) )。

{

$ this-_ database connection=$ database connection;

}

}

$book=new Book (;

$ book-set数据库($ database connection );

此代码允许此book类用于任何web程序。 除了程序开发人员在创建对象后立即提供数据库之外,此book不再依赖于任何内容。

这取决于最好的方法——注入。

依赖注入的两种常见方法

结构注入

注:构造函数。 这个译文好像不合适。 类中的此方法经常用于初始化特定属性

构造器注入包括将所有依赖关系作为参数传递给新创建的对象。 就像这样。 $ book=new book ($数据库连接,$configFile );

明星注入

的依赖越多,构造就越杂乱。 还有一些其他原因导致了不好的方法,例如代码重用和结构任务。

这必须用其他方法进行依赖注入,称为设置注入。 在需要注入依赖关系的对象上创建公共方法。 $book=new Book ();

$ book-set数据库($ database connection );

$ book-set config文件($ config file;

这很容易实现,但会在程序中写大量的代码。 创建book对象时,需要三行代码。 如果必须注入其他依赖项,则必须添加第四行代码。 这也很快就会一团糟。

工厂的班级

解决这些问题的对策是使用工厂工厂工厂。 工厂是用于创建和注入对象的所有依赖关系的类。 例如class Factory {

公共静态$ _ database;

publi

c static function makeBook()

{

$book = new Book();

$book->setDatabase(self::$_database);

// more injection...(更多注入)

return $book;

}

}

然后:$book = Factory::makeBook();

所有的依赖在运行期间都应在此 factory 对象中注册。它现在是大门,在依赖与任何对象打交道前,都必经此门。

makeBook 作为一个静态方法的原因是易用并且可以在全局得到。在本文开头,我提出使用 singleton 类型和全局变量对代码而言是一个糟糕的选择。多数情形下,确实如此!当他们控制接入时,是一个差设计。但是在他们控制创建时,是一个不错的选择。makeBook 方法仅仅是创建的一个捷径。在 book 类和 factory 类之间,没有任何依赖。由于 factory 类的存在,我们的依赖可以存放在一个地点,并且用一行创建代码就可自动注入这些依赖。

此处的 factory 或者容器类移走了依赖注入的所有额外工作。

以前的注入:$book = new Book();

目前的方法:$book= Factory::makeBook();

几乎没有任何的额外工作,但是有大量益处。

当运行测试代码时,尤其是单元测试,其目标是检查类中的方法是否正确地工作。由于 book 类要求接入数据库并且读取图书数据,它增加了一层复杂度。此测试不得不进行数据库连接,取得数据,然后测试它。瞬间,测试不再是测试 book 类中的单个方法,它目前同时也测试数据库。如果数据库离线,测试就会失败。这已经远离了单元测试的目的。

解决上述问题的方法是用不同的数据库依赖来作单元测试。当测试套件开始时,虚拟的数据库被注入 book。虚拟数据库将永远拥有开发人员所期待的数据。如果使用一个真实数据库,数据的潜在变化会导致测试不必要的失败。当数据库的记录改变了,不需因此重新进行单元测试。

此代码现在更加模块化,因为它可以被放到任何其他的网页程序。创建 book 对象并且用 $book->setDatabase() 注入数据库连接。此时,数据库在 Registery::Database、$database 或者 $someRandomDatabaseVarible 都无关大局。只要有一个数据库连接,book就可以在任何系统内工作。

代码更加易维护,因为每个对象都被赋予了它的所需。如果同一类的实例需要不同的数据库连接,在类内部一点儿也不需要额外的代码。例如 book1 连接到 数据库1,book2 连接到 数据库2Factory::$_database=$ourDatabaseVarForDB1;

$book1= Factory::makeBook();

$book2= Factory::makeBook();

$book2->setDatabase($database2);

依赖注入真的是更易维护,更易测试和更加模块化的最佳解决方案。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。