gpt4 book ai didi

php - 在构造函数中使用 "new"关键字

转载 作者:可可西里 更新时间:2023-10-31 23:54:54 24 4
gpt4 key购买 nike

我最近读到在构造函数中使用关键字“new”是非常不受欢迎的,但我不确定我是否理解为什么?例如,如何:

class A {
public $foo;

function __construct() {
$this->foo = new Bar();
}
}

任何不同于:

class A {
public function someMethod() {
$foo = new Bar();
}
}

???

最佳答案

这确实是依赖注入(inject)背后的理论。

并不是说使用“new”本身就是个坏主意。相反,通过在您的类内部实例化对象,您正在创建硬依赖关系,如果不更改类本身,这些依赖关系将永远无法更改或切换。

它也违反了“编码到接口(interface),而不是实现”的范例

例子:

class Phone {
protected $network;

public function __construct() {
$this->network = new Verizon();
$this->network->distinctiveRing();
}
}

class Verizon {
public function call($number) {
....
}

public function distinctiveRing() {

}
}

现在,假设有一天您想要创建一部 ATT、TMobile 和 Sprint 手机?当然,他们都可以打电话,而且只需一个电话号码就可以打电话。此外,电话类不应该关心运营商是谁,因为它的工作是方便输入号码 - 而不是实际建立网络连接,对吧?

所以,话虽这么说,我们不应该创建一个新的 SprintPhone 类来实例化另一个 Sprint 网络对象,对吧?对。

那么什么是更好的方法呢?

class Phone {
protected $network;

public function __construct(NetworkInterface $network) {
$this->network = $network;
}
}

interface NetworkInterface {
public function call($number);
}

class Verizon implements NetworkInterface {
...
}

class Sprint implements NetworkInterface {
...
}

现在,您可以说:$phone = new Phone(new Sprint())$phone = new Phone(new Verizon())

另请注意,我们对 distinctiveRing 的调用已消失。为什么?好吧,因为我们不知道任何实现 NetworkInterface 的对象都一定会支持独特的环。 但这很好,因为现在我们的 Phone 可以支持任何 Network,无需更改代码。

如果你想支持独特的铃声,你总是可以创建一个支持distinctiveRing方法的新接口(interface)。在您的 Phone 对象中,您可以检查您的 Network implements DistinctiveRingerInterface,如果是,则制作您的特色铃声.但是使用这种方法您不再受限于特定网络。更好的是,您被迫这样做是因为您从一开始就采取了正确的方法。

以及以后可以创建的任何其他网络。更重要的是,您的类不再需要关心它所提供的网络对象的类型。它知道(因为它接收到一个实现 NetworkInterface 的对象),Network 对象能够使用 $number 进行调用

这也往往会导致更好的代码,以及更好的关注点分离。

最后:测试。

对于第一个示例,如果您尝试测试您的 Phone 对象,它将在 Verizon 网络上调用电话。因为你正在运行单元测试而整天被打电话的人很糟糕,对吧?对。

好吧,只需创建一个实现 NetworkInterface 的 TestNetwork 类,并将其传递给您的电话对象。您的 TestNetwork 类可以在它的 call 方法中做任何您想做的事情——或者什么也不做。

此外,您可以使用 PHPUnit 创建模拟对象,并确保实际调用 TestNetwork 上的 call 方法。之前您无法执行此操作,因为 Network 是在您的 Phone 中实例化的。

关于php - 在构造函数中使用 "new"关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14219966/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com