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?
Dependency injection moves the dependencies to the interface of components. This makes it easier to see what dependencies a component has, making the code more readable. You don't have to look through all the code to see what dependencies you need to satisfy for a given component. They are all visible in the interface.
If there are no constructors written for a class, Java provides a no-argument default constructor where the instance variables are set to their default values. For int and double variables, the default value used is 0, and for String and other object variables, the default is null.
The main disadvantage to Constructor Injection is that if the class you're building is called by your current application framework, you might need to customize that framework to support it. Some frameworks assume that your classes will have a parameterless constructor.
StructureMap. From the project website: “StructureMap is the oldest, continuously used IoC/DI container for . NET dating back to its first public release in June 2004 on . NET 1.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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With