依赖注入模式中,为什么用对象而不是用数组传递?
Posted sunshineliulu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了依赖注入模式中,为什么用对象而不是用数组传递?相关的知识,希望对你有一定的参考价值。
依赖注入(Dependence Injection, DI) 依赖注入是控制反转的一种设计模式。依赖注入的核心是把类所依赖的单元的实例化过程,放到类的外面去实现。依赖注入的实现离不开反射。
依赖注入(Dependence Injection, DI)
所谓的依赖注入,指将依赖的对象通过参数的形式一次性传入,使用时不需要显式 new
了,比如把A类所依赖的B类、C类等以属性或者构造函数等方式注入A类而不是直接在A类中实例化。
只要不是由内部生产(比如初始化、构造函数中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI) 。
依赖注入需要利用反射实现,比如:
class A
{
protected $b;
public function __constrcut(B $b)
{
$this->b = $b;
}
}
// 通过控制反转容器生成 A 的实例时,会通过反射发现 A 的构造函数需要一个 B 类的实例
// 于是自动向 A 类的构造函数注入 B 类的实例
$a = IoC::make(A::class);
依赖注入的实质就是把一个类不可更换的部分
和可更换的部分
分离开来,通过注入
的方式来使用,从而达到解耦的目的。
比如有一个 mysql
数据库连接类如下:
class Mysql {
private $host;
private $port;
private $username;
private $password;
private $db_name;
public function construct(){
$this->host = '127.0.0.1';
$this->port = 22;
$this->username = 'root';
$this->password = '';
$this->db_name = 'db';
}
public function connect()
{
return mysqli_connect($this->host,$this->username ,$this->password,$this->db_name,$this->port);
}
}
// 使用
$db = new Mysql();
$con = $db->connect();
可更换部分是数据库的配置
class Configuration
{
private $host;
private $port;
private $username;
private $password;
private $db_name;
public function construct(string $host, int $port, string $username, string $password,string $db_name)
{
$this->host = $host;
$this->port = $port;
$this->username = $username;
$this->password = $password;
$this->db_name = $db_name;
}
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;
}
public function getDbName(): string
{
return $this->db_name;
}
}
不可更换部分是Mysql数据库的连接操作
class Mysql
{
private $configuration;
public function construct(DatabaseConfiguration $config)
{
$this->configuration = $config;
}
public function connect(){
return mysqli_connect($this->configuration->getHost(),$this->configuration->getUsername() ,
$this->configuration->getPassword,$this->configuration->getDbName(),$this->configuration->getPort());
}
}
这样就完成了配置文件和连接逻辑的分离,使用如下:
$config = new Configuration('127.0.0.1', 'root', '', 'my_db', 22);
$db = new Mysql($config);
$con = $db->connect();
$config是注入Mysql的,这就是所谓的依赖注入。
总结
注入可以理解成从外面把东西打进去。因此,依赖注入模式中,要分清内和外,要解除依赖的类内部就是内,实例化所依赖单元的地方就是外。在外通过构造形参,为类内部的抽象单元提供实例化,达到解耦的目的,使下层依赖于上层,而不是上层依赖于下层。
因此,依赖注入模式中,要用对象传递,通过一个实例的反射来实现,这是数组做不到的。
以上是关于依赖注入模式中,为什么用对象而不是用数组传递?的主要内容,如果未能解决你的问题,请参考以下文章
spring依赖注入,和控制反转。用自己的话说是怎么说的。最好能够用代码来解释