Default values in dependency injection

2019-04-28 16:51发布

问题:

I currently have a class with tightly coupled dependencies, and the class constructor doesn't currently have any parameters. I'm trying to be able to optionally pass in different dependencies without changing the constructor signature and thus breaking applications that currently use the class.

I came up with this pattern:

class Car {
    private $engine;

    public function __construct($options = array()) {
        if (isset($options['engine']) {
            $this->engine = $options['engine'];
        } else {
            $this->engine = new Engine();
        }
    }
}

This way Car could still be created (with a default engine) with new car(), or by passing in a custom engine: new Car(array('engine' => new CustomEngine())).

Is this a correct way to do this? What problems does this have with maintainability?

回答1:

This is a correct pattern in my opinion, I use it often.

Dependency injection allows the user of the class to provide the dependencies. With your code, it's possible, so I don't see a problem with it.

The only thing I do differently though is that I use explicit parameters, so that I can type-hint the objects to make sure they are of the correct class, and to make it easier to know what parameters can be passed without looking at the code:

class Car {
    private $engine;

    public function __construct(Engine $engine = null) {
        $this->engine = $engine ?: new Engine();
    }
}