构造函数注入
对象通常依赖于其他对象。应该将依赖项作为参数传递给构造函数,而不是在构造函数中创建依赖项。这确保了对象之间没有紧密耦合,并且能够改变对类实例化的依赖性。这有许多好处,包括通过使依赖项显式化使代码更容易阅读,以及使测试更简单,因为可以更容易地切换和模拟依赖项。
在以下示例中,Component
将取决于 Logger
的实例,但它不会创建一个。它需要将一个作为参数传递给构造函数。
interface Logger {
public function log(string $message);
}
class Component {
private $logger;
public function __construct(Logger $logger) {
$this->logger = $logger;
}
}
没有依赖注入,代码可能看起来类似于:
class Component {
private $logger;
public function __construct() {
$this->logger = new FooLogger();
}
}
使用 new
在构造函数中创建新对象表示未使用依赖注入(或未使用不完整),并且代码紧密耦合。这也表明代码未经过严格测试,或者可能有严格的测试,对程序状态做出错误的假设。
在上面的示例中,我们使用依赖注入,如果需要,我们可以轻松地更改为不同的 Logger。例如,我们可能使用记录到不同位置的 Logger 实现,或使用不同日志记录格式的 Logger 实现,或者记录到数据库而不是文件的 Logger 实现。