Alex Rivera | Logout

The composite pattern/entity system and traditional OOP

Asked 2011-02-09T06:30:10.127
18

I'm working on a small game written in Java (but the question is language-agnostic). Since I wanted to explore various design patterns, I got hung up on the Composite pattern/Entity system (which I originally read about here and here) as an alternative to typical deep hierarchical inheritance.

Now, after writing several thousand lines of code, I'm a bit confused. I think understand the pattern and I enjoy using it. I think it's very cool and Starbucks-ish, but it feels that the benefit it provides is somewhat short-lived and (what irks me most) heavily dependent on your granularity.

Here's a picture from the second article above: enter image description here

I love the way objects (Game entities, or whatever you want to call them) have a minimal set of components and the inferred idea is that you could write code that looks something like:

BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();

Alien.addComponent(new Position(), new Movement(), new Render(), new Script(), new Target());
Player.addComponent(new Position(), new Movement(), new Render(), new Script(), new Physics());

.. which would be really nice... but in REALITY, the code ends up looking something like

BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();

Alien.addComponent(new Position(), new AlienAIMovement(), new RenderAlien(), new ScriptAlien(), new Target());
Player.addComponent(new Position(), new KeyboardInputMovement(), new RenderPlayer(), new ScriptPlayer(), new PhysicsPlayer());

It seems that I end up having some

Edit
Report

1 Answer

2

David,

first thank you for your perfect question.

I understand your problem and think that you did not use the pattern correctly. Please read this article: http://en.wikipedia.org/wiki/Composite_pattern

If for example you cannot implement general class Movement and need AlienAIMovement and KeyboardMovement you probably should use Visitor pattern. But before your are starting refactoring of thousands of code lines check whether you can do the following.

Is it a chance to write class Movement that accepts parameter of type BaseEntity? Probably the difference between all implementations of Movement is just a parameter, flag or so? In this case your code will look like:

Alien.addComponent(new Position(), new Movement(Alien), new Render(Alien), new Script(Alien), new Target());

I think it is not so bad.

If it is not possible, try to create instances using factory, so

Alien.addComponent(f.createPosition(), f.createMovement(Alien), f.createRender(Alien), f.createRenderScript(Alien), f.createTarget());

I hope my suggestions help.

answered 2011-02-09T08:20:37.667

Your Answer