依赖关系注入仅用于测试


Dependency injection is only for testing?

我读了很多次硬编码对象不是一个好的做法:

class Session
{
    private $user;
    function __construct()
    {
        $this->user = new User();
    }
}

它的坏只是因为它无法测试的行为?我只是发现这种硬编码更容易阅读。当然,我可以将这些方法添加为类似DI的方法:

    public function setUser (User $userObj)
    {
        $this->user = $userObj;
    }
    public function getUser()
    {
        return $this->user;
    }

但它就像一个房子,甚至可以改变桁架。为什么?

与房屋不同,房屋是一个物理对象,桁架无法更改,这是代码,其中事物不太永久。

老实说,使用DI多年,我认为它被过度使用。很简单:一堆类的依赖项不会改变,如果它们改变了,那么 DI 应用于它们就很容易了。

坚持房屋类比,我的立场变成了"现在不一定要建造整个房屋扩建部分,但也不要在可能需要门的地方建造承重墙"。我会在你的构造函数中创建你的依赖对象,所以如果有必要使它们可交换,很容易添加一个构造函数参数,如果需要的话,通过 DI 框架开始传递依赖关系。

然后,您保持开放的一件事是,创建该类的每个实例都需要替换为DI友好版本,这意味着大量的重构,因此需要进行大量的回归测试。这是一个很大的风险。如果您确保拥有非常彻底的自动化测试覆盖率,则可以减轻很多风险。

另一方面。。。从一开始就使用 DI 框架,即使没有立即注入依赖项,当需要注入依赖项时,它仍然会进一步减轻这种考虑。

使用 DI 确实会使您的测试变得更加容易,这反过来又会提高您实现更高测试覆盖率的能力。但我也不认为应该专门为测试而编码。

因此,在做出此决定时,有一些事情需要权衡并应用于您的特定风格和要求。