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
ShipandBullet - Create interfaces to represent these components. Eg. I can expect a
PositionableComponent.getXmethod. - Create component classes like
PositionableComponent,DrawableComponentwhich implement my interface - Entities like
Shipwill have components likePositionableComponent. They will implement the methods by internally keeping an instance of apositionalbleComponentand 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