依赖注入模式 目的 为了实现松散耦合的架构,以获得更好的可测试、可维护和可扩展的代码。
用法 下面的代码 定义了 DatabaseConfiguration 类,该类的实例将被注入到 DatabaseConnection 对象中。DatabaseConnection 会从注入的 DatabaseConfiguration 中获取所有需要的变量。如果不使用依赖注入的方式,数据库配置对象将直接在 DatabaseConnection 中创建,这不利于测试和扩展。
使用场景
Doctrine2 中的 ORM 使用了依赖注入。例如,它使用的配置是注入到 Connection 对象中的。为了方便测试,我们可以很轻松地创建一个模拟配置对象,并将其注入到 Connection 对象中
许多框架已经实现了依赖注入容器,通过配置数组来创建对象,并在需要的地方注入它们(例如,在控制器中)
UML 类图
代码 DatabaseConfiguration.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?php declare (strict_types = 1 );namespace DesignPatterns \Extend \DependencyInjection ;class DatabaseConfiguration { private string $host ; private int $port ; private string $username ; private string $password ; public function __construct (string $host , int $port , string $username , string $password ) { $this ->host = $host ; $this ->port = $port ; $this ->username = $username ; $this ->password = $password ; } public function getHost ( ): string { return $this ->host; } public function getPort ( ): int { return $this ->port; } public function getUsername ( ): string { return $this ->username; } public function getPassword ( ): string { return $this ->password; } }
DatabaseConnection.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php declare (strict_types = 1 );namespace DesignPatterns \Extend \DependencyInjection ;class DatabaseConnection { private DatabaseConfiguration $configuration ; public function __construct (DatabaseConfiguration $config ) { $this ->configuration = $config ; } public function getDsn ( ): string { return sprintf ( '%s:%s@%s:%d' , $this ->configuration->getUsername (), $this ->configuration->getPassword (), $this ->configuration->getHost (), $this ->configuration->getPort () ); } }
测试 Tests/DependencyInjectionTest.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php declare (strict_types = 1 );namespace DesignPatterns \Extend \DependencyInjection \Tests ;use DesignPatterns \Extend \DependencyInjection \DatabaseConfiguration ;use DesignPatterns \Extend \DependencyInjection \DatabaseConnection ;use PHPUnit \Framework \TestCase ;class DependencyInjectionTest extends TestCase { public function testDependencyInjection ( ) { $config = new DatabaseConfiguration ('localhost' , 3306 , 'domnikl' , '1234' ); $connection = new DatabaseConnection ($config ); $this ->assertSame ('domnikl:1234@localhost:3306' , $connection ->getDsn ()); } }