Wednesday, January 3, 2018

dependency injection - Getting Started with Component Architecture: DI?


TLDR: if I have entities like Ship and Bullet and components like Positionable and Drawable, should I create interfaces for each component and inject them into my entities using DI, or should I be doing something else?



(In this case, Ship would extend IPositionable and have an instance of a PositionableComponent which is injected by DI. Any calls to ship.getX or ship.setX would be implemented as myPositionable.getX or myPositionable.setX.)




I just moved away from MVC towards something more component-architecture-like. I have no concept of messages yet (it's rough prototype code), objects just get internal properties and values of other classes for now.


That issue aside, it seems like this is turning into an aspect-oriented-programming challenge. I've noticed that all entities with, for example, a position component will have similar properties (get/set X/Y/Z, rotation, velocity).


Is it a common practice, and/or good idea, to push these behind an interface and use dependency injection to inject a generic class (eg. PositionComponent) which already has all the boiler-plate code?


(I'm sure the answer will affect the model I use for message/passing)


Edit: The DI model I'm proposing is as follows.



  • Create entity classes like Ship and Bullet

  • Create interfaces to represent these components. Eg. I can expect a PositionableComponent.getX method.


  • Create component classes like PositionableComponent, DrawableComponent which implement my interface

  • Entities like Ship will have components like PositionableComponent. They will implement the methods by internally keeping an instance of a positionalbleComponent and redirecting all interface calls to the component.

  • My DI framework will (presumably automatically) wire up components by interface, eg. Ship._positionableComponent = new PositionableComponent(). This is how NInject works, which is the only framework I've ever used (and I'm working in Haxe now).


This will allow me to work on a higher level (ships contain components), and reduce boilerplate code (component implementations), but introduces duplicate code (redirecting to the internal component). Since I'm working in Haxe, I may be able to avoid writing that boilerplate by hand.


However, the advantage is that I can override component behaviours. If undeadMonster.IsAlive() should return true when its HP is above -100 (instead of 0), I can easily code this, and the change becomes very visible from the code level.


But I'm not sure if I'm solving this correctly.




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...