一、依赖注入的三种实现方式 php
依赖注入是一种编程技术,目的是为了降低耦合性、提高可测试性和可扩展性,它可以将对象之间的依赖关系从程序中抽象出来并在外部进行管理,从而使程序更加灵活。而在 php 中,实现依赖注入有三种方式,分别是构造器注入、属性注入、方法注入。
构造器注入
class Person{
public function __construct(Car $car){
$this->car = $car;
}
}
$car = new Car();
$person = new Person($car);
构造器注入是一种通过类的构造器方法接收依赖对象的方式。在上述代码中,Person 类需要一个 Car 类的实例,所以在其构造器中声明了一个参数 $car,通过参数传递的方式将 Car 的实例传递给了 Person 的构造器,而 Person 对象在实例化时则会自动将传入的 Car 实例赋值给自己的 $car 属性。
属性注入
class Person{
public $car;
}
$car = new Car();
$person = new Person();
$person->car = $car;
属性注入是一种通过声明类的公共属性来接收依赖对象的方式。通过公共属性直接将Car类的实例赋值给Person类的属性 $car,实现依赖注入。
方法注入
class Person{
public $car;
public function setCar(Car $car){
$this->car = $car;
}
}
$car = new Car();
$person = new Person();
$person->setCar($car);
方法注入是一种通过类的公共方法来接收依赖对象的方式。Person 类中声明了一个 setCar 方法,通过方法传递 Car 的实例并将其赋值给 $car 属性,实现依赖注入。
二、依赖注入的两种实现方式
构造器依赖注入
class Person{
public function __construct(Car $car){
$this->car = $car;
}
}
$car = new Car();
$person = new Person($car);
构造器依赖注入,在构造函数中依赖对象
Setter 方法依赖注入
class Person{
public $car;
public function setCar(Car $car){
$this->car = $car;
}
}
$car = new Car();
$person = new Person();
$person->setCar($car);
Setter 方法依赖注入,在 Setter 方法中依赖对象
三、依赖注入的三种实现方式区别
构造器依赖注入:类似于参数传入,它将依赖关系放到构造函数中,使代码更加清晰明了,并且遵循了单一职责原则。容易维护和测试,但是在依赖链过长时,代码可读性会下降。如果创建新对象时初始化参数缺失,则需要重载构造函数并传入缺失的参数。
Setter 方法依赖注入:Setter 方法依赖注入是在代码运行期间通过 Setter 方法设置依赖关系。相比于构造器注入,Setter 方法依赖注入更加灵活,可以省略一些必需的参数,而且对于可选依赖项也能更好地支持。缺点是它隐藏了类的依赖关系,难以确定依赖的位置,代码可读性差。
属性注入:属性注入是一种非常简单的依赖注入方法,但是它的缺点在于实现上的灵活性差,在某些情况下会破坏封装性,降低代码的可测试性。而且属性注入容易让人忽略依赖关系,导致类之间产生紧密的耦合。
四、依赖注入的三种实现方式的优缺点
构造器注入的优缺点
优点:
1. 遵循了单一职责原则;
2. 依赖关系直观。
缺点:
1. 构造函数的参数数量容易增多;
2. 构造函数多次调用会导致性能问题。
Setter 方法注入的优缺点
优点:
1. 灵活性比较高,可以在对象实例化后动态修改对象;
2. 在依赖环节比较棘手的情况下,可以通过 Setter 方法注入来像拼图一样解决。
缺点:
1. Setter 方法可能会被滥用,使得类的依赖关系更加难以理解;
2. 需要修改对象状态,会影响对象的一致性和不可变性;
3. 依赖关系不可见。
属性注入的优缺点
优点:
1. 比较简单容易理解;
2. 在创建对象实例时仅需要一行代码。
缺点:
1. 会破坏对象的封装性;
2. 对象的创建和依赖关系之间易混淆;
3. 依赖关系不可见。
五、依赖注入的三种方式
构造器注入
class Person {
private $car;
public function __construct(Car $car) {
$this->car = $car;
}
}
$car = new Car();
$person = new Person($car);
Setter 方法注入
class Person{
private $car;
public function setCar(Car $car){
$this->car = $car;
}
}
$car = new Car();
$person = new Person();
$person->setCar($car);
属性注入
class Person{
public $car;
}
$car = new Car();
$person = new Person();
$person->car = $car;
六、spring 常用的三种注入方式
Setter 注入
将依赖项暴露为符合 JDK Java Bean 规范的 Bean 属性导出,并通过 Bean 属性设置进行注入。
构造器注入
在 Bean 定义文件中声明构造器函数,并将 Bean 的依赖项传递给构造器函数。
Auto-wiring 注入
自动装配是一种通过 Spring 容器自动确定 Bean 依赖关系的方法。在自动装配过程中,Spring 容器会自动将 Bean 之间的依赖关系映射到相应的 Bean 属性或构造器参数上。
七、总结
依赖注入是一种为了降低耦合性、提高可测试性和可扩展性的编程技术。在 php 中,有三种实现依赖注入的方式,分别是构造器注入、属性注入、方法注入。这三种方式各有优缺点,需要根据具体业务场景选择合适的实现方式。
在 spring 中,常用的三种实现依赖注入的方式是 Setter 注入、构造器注入、Auto-wiring 注入,相对于 php 中的实现方式,更加灵活和复杂,但也更加强大。