Take the 2-minute tour ×

I typically try and avoid bidirectional relationships at all costs. Recently I've been trying to follow a more domain centric design philosophy and I'm looking for advice in the best way to solve a specific problem.

I am implementing a basic 2d grid. There are 3 basic classes, Item, Tile (has a list of Items), and World (has a 2d array of Tiles).

I am struggling with where to put the move() method which moves an item from one tile to a neighboring tile. My initial inclination would be to place the move method in the Item class since it is the item that is actually moving.

However, that would create a circular dependency. In the past I always worked with dumb objects in which case the move() method was in a higher layer (some kind of WorldManager or MoveManager) which knows about both tiles and items. I'm interested in what proposals others might have that can avoid the circular dependency while maintaining the domain-centric philosophy.

share|improve this question
The title sounds like human relationship –  superM Aug 11 '12 at 10:37
add comment

2 Answers

up vote 3 down vote accepted

To answer your question directly:

A player would tell (by picking it up) an item to move from one tile to another. So logically, the move method goes on Item and receives the two Tiles as parameters.

Now having said that:

Don't let DDD get in the way of single-responsibility principle. It's ok to have non-entity items, such as MoveManager, and call it part of your domain. Just because you don't persist it anywhere, doesn't make it less a part of the domain.

People often confuse the data model with the behaviour (or business domain) model when talking about DDD. Anything can be an entity. In fact, one could argue that anything persisted already has its single responsibility and shouldn't be given any more.

From MSDN:

I, for one, am not disturbed by the need to involve other, non-entity classes, and I would try to avoid lifting the central behavior outside of my entity. You should always remember that entities are intrinsically behavioral units. Often that behavior will be implemented as a kind of state machine—when you invoke a command on an entity, it is responsible for changing its internal state—but sometimes it's necessary for you to obtain additional data or impose side-effects upon the outside world.

share|improve this answer
Great answer. I don't know why I didn't think of passing both tiles in. My problem was that I was assuming the MoveManager lived above the Item and the Tile. This would lead to the Item becoming a POJO. However, the MSDN article (and your answer) would suggest the Item lives above the MoveManager and passes the tiles down to the MoveManager, which knows about all the logic of handling collisions, etc. –  Pace Aug 11 '12 at 0:58
add comment

Hmm, I like the MoveManager idea better.

Any object that moves itself would also require knowledge of the underlying surface on which it is moving, so you would have to pass the tileset to your Item anyway. There goes your loose coupling.

Seems to me like it makes more sense to have a MoveManager object that has knowledge of the tileset and the items. This is how the real world works; the chess pieces and the chess board don't have any built-in intelligence of their own.

share|improve this answer
add comment

Your Answer


