John Smith
John Smith

Reputation: 6207

Dependency injection is only for testing?

I read many times that hardcoding object is not a good practice:

class Session
{
    private $user;

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

its bad only because of its untestable behaviour? I simply find this hardcoding easier to read. Of course I can add those methods to be DI-like:

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

    public function getUser()
    {
        return $this->user;
    }

But then its like a house where even the trussing can be changed. What for?

Upvotes: 1

Views: 477

Answers (1)

Adam Cameron
Adam Cameron

Reputation: 29870

Unlike a house, which is a physical object and where the trussing can't be changed, this is code, wherein things are less permanent.

To be honest, having used DI for years I think it's overused. Quite simply: a bunch of a class's dependencies won't change, and if they do,it's easy enough to then apply DI to them.

Sticking with the house analogy, my position is becoming "don't necessarily build the entire house extension now, but also don't build a load-bearing wall where a door might need to go". I'd create your dependency objects in your constructor, so if it ever becomes necessary to make them swapabble, it's easy enough to add a constructor arg and start passing the dependency in via a DI framework if needs must.

One thing you're leaving yourself open for then is that every instance where that class is created will then need to be replaced with a DI-friendly version, which means a lot of refactoring, and accordingly a lot of regression testing. This is a heavy risk. If you make sure you've got very thorough automated test coverage, a lot of this risk is mitigated.

On the other hand... using a DI framework from the outset, even if the dependencies aren't injected immediately, it'll still mitigate this consideration even more, when it comes time to need to inject them.

Using DI certainly does make your testing a lot easier, which in turn will increase your ability to achieve higher test coverage. But I also don't think one should code specifically for testing.

So there's a few things to weigh-up and apply to your specific style and requirements when making this decision.

Upvotes: 4

Related Questions