I've been reading about dependency injection and have a simple question. I can understand how via constructor or setter injection required dependencies are autowired by the DI framework. What happens when an object decides it needs to create a new object due to some business process? Do I need to always create a Factory in these situations? To make it a less abstract question, here is an example.
Let's say I'm writing a game of Asteriods. There's a ship in the middle which can spin around and shoot the asteriods. Assume that the ship has been created and approriate things injected. When playerShip.shoot()
is called we need to create a bullet
object. The bullet object needs to know which way it is going (direction
) and where to start (point
).
Normally, I would do something like this:
bullet = new Bullet( direction, point );
However, that tightly couples the PlayerShip class to the Bullet class. How should this work under dependency injection? Do I need to create a BulletFactory interface and inject an implementation of that into the ship?
Edit: I'm not actually writing asteriods. This was a simple example that I thought people would understand. I wanted something that needed to be created a runtime (not while "wiring up objects") that also had parameters to it's constructor.
You will always have to create a new object by instantiating a class at some point. Dependency injection also requires creating new objects. Dependency injection really comes into play when you want to control or verify the behavior of instances used by a class that you use or want to test.
Dependency injection is the principle that the objects which a class needs should be 'injected' into it, not created inside it. Injection usually happens through the constructor, where a class receives any objects it needs as constructor parameters.
The goal of the dependency injection technique is to remove this dependency by separating the usage from the creation of the object. This reduces the amount of required boilerplate code and improves flexibility.
There are three types of dependency injection — constructor injection, method injection, and property injection.
Depends if you just going to have just one bullet type...
If just one then I would say you'd be ok.
But if you have a Bullet, DoubleBullet, PowerBullet, NukeBullet, etc.
Then I would make Bullet base class and all the other Derrived from it
Then I would make Bullet factory and it would have CreateBullet, CreatePowerBullet, etc.
The other question is will anything else be making a bullet? If so then I would create a factory to consolidate the creation logic in one place...
Otherwise it smells like your using DI just to be using DI...
You've pretty much got it. If you want to be decoupled with the Bullet
class, then in my opinion the best solution is to inject a factory that can create Bullet
objects.
Note that you have several levels of indirection you can take, each giving you more flexibility, but requiring more code and possibly being more difficult to understand. The simplest is to have BulletFactory
and Bullet
both be concrete types. This means you can't easily have different implementations of them, but you can still extend them both and pass in a subclass of BulletFactory
that returns subclasses of Bullet
. If your only purpose for injection is to make unit tests easier, this is the route I would take. Of course, you can also make BulletFactory
an interface, or Bullet
an interface, or both. If you're going to have different implements of either for non-testing purposes, this is the route I would take.
Finally, you have to decide if the benefits of decoupling the Bullet
class from your PlayerShip
class are worth it. Tight coupling is not evil and shouldn't be avoided at all costs—it makes sense in some contexts, and not in others. Only experience will help you figure out when to couple classes and when to decouple them.
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