views:

708

answers:

1

Hello,

I'm writing a PHP application with testability in mind, so my classes always ask in their constructors for the "collaborator objects" they depend on, in respect to the Dependency Injection pattern.

That way, I'm able to pass in mocks or test implementations in my unit tests.

What I want to achieve though, is to be able to instantiate a class with null values passed to its constructor arguments, in order to trigger a fallback mechanism which instantiates a default implementation class for each collaborator.

Because object-type parameters cannot be given a default value in PHP, I have to do it inside the constructor. The following code is an example of the approach I'm currently using :

class Engine
{
    private $loader;
    private $logger;

    public function __construct(ResourceLoader $loader = null, Logger $logger = null)
    {
        if ($loader == null) $loader = new DefaultResourceLoader;
        if ($logger == null) $logger = new DefaultLogger;

        $this->loader = $loader;
        $this->logger = $logger;
    }
}

What do you think of this ? Should I use an IoC container instead or is there another way of giving object-type arguments a default value ?

+2  A: 

Of course you'd better use an IoC/DIP container to do the job. Your code above (the if statements) increase the coupling of the classes. The client class (Engine) should not care what’s implementing the loader and logger roles. That’s the factory’s or DIP container work to know this. By putting a concrete class name into your code and bind the classes together making your code less flexible (agile), less reusable and thus less maintainable.

Thanks for your answer. Have you got any recommandation for a good PHP container ?
Franck