php中new与构造函数,php - 在构造函数中使用“ new”关键字 - SO中文参考 - www.soinside.com...

这实际上是依赖项注入背后的理论。

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

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

示例: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手机?当然,他们所有人都可以打电话,而且只要有电话号码就可以打电话。另外,电话班级不必关心运营商是谁,因为它的工作是方便输入号码-而不是实际建立网络连接,对吗?

因此,我们不必创建一个可以实例化另一个Sprint网络对象的新SprintPhone类,对吗?对。

那还有什么更好的方法?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可以支持ANY Network,而无需更改代码。

如果要支持特殊振铃,则始终可以创建一个支持distinctiveRing方法的新接口。在Phone对象中,可以检查Network implements DistinctiveRingerInterface,如果是,则制作独特的戒指。但是,您不再需要使用这种方法来绑定特定的网络。更好的是,您被迫这样做,因为从一开始就采取了正确的方法。

而且,以后可以创建任何其他可行的网络。更重要的是,您的班级不再需要关心它所提供的哪种网络对象。它知道(因为它接收到一个实现NetworkInterface的对象),所以Network对象能够用call来创建$number。

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

最后是测试。

在第一个示例中,如果您尝试测试Phone对象,它将在Verizon网络上进行呼叫。很糟,因为您正在运行单元测试,所以整天都被打来电话,对吧?对。

好,只需创建一个实现NetworkInterface的TestNetwork类,然后将其传递给您的电话对象。您的TestNetwork类可以在call方法中执行任何您想执行的操作-或不执行任何操作。

此外,您可以只使用PHPUnit创建一个模拟对象,并确保您的TestNetwork上的call方法实际上得到了调用。您以前无法执行此操作,因为Network已在Phone内部实例化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值