So I've got a solution that contains a few big projects, which I'm trying to break down into smaller projects with more isolated responsibilities. This is a game I'm tinkering with -- I'm mainly a LOB developer and I think the principles are universal, so I'm hoping to learn something here.

The dependencies in some of the objects are a bit too tightly intertwined, and I'm hoping for some help on how to untangle them. Or maybe some sort of pattern or abstraction that might make them more manageable.

Ares.Core.World has classes in it like Creatures, Items, etc. All of them inherit from Entity, which is aware of what cell on the map it exist at. It accomplishes this by holding a reference to a Ares.Core.UI.MapControls.MapCell... And you can see that the wires are already getting crossed.

Ares.Core.UI.MapControls contains Map and MapCell, each of which contain Lists of creatures and items that they contain. MapCell also inherits from Ares.Core.World.Entity since that solved a few early problems very elegantly -- for instance, all Entities have inventory.

I would like to find a way to split UI and World out into seperate projects (Ares.World and Ares.UI) since UI and the overarching world should probably be seperate concerns. But as you can see, the way it is now the two projects would need to reference each other, and circular references are not allowed.

I'm wondering if there are any architectural patterns out there that might help in this situation. Thanks!

  • Can you clarify what you mean by "reference"? Are you referring to assembly references or object references? – Kevin Hsu May 19 '11 at 22:21
  • Little of both. Ares.Core.World and Ares.Core.UI are projects. Entity is a class in World. Creature and Item are classes that inherit from Entity. Map and MapCell are classes in UI.MapControls. – Brian MacKay May 19 '11 at 23:37
  • You might want to go with a factory pattern. Assuming you have an object in World, called, well, World, you might go with something like: Creature c = (Creature) myWorld.CreateEntity(...); – Kevin Hsu May 19 '11 at 23:45
  • @Kevin Hsu: thanks, but how does that get around the circular reference problem? The problem is that things in the World project need to know about classes in UI, but then those World items need to get instantiated in UI. This is not allowed. Right now what I'm doing is making interfaces for everything in a third project. But that's slowly pulling the project out of whack -- certain pieces must end up being in that third project with the interfaces. I feel like there must be a better way. – Brian MacKay May 20 '11 at 3:42
  • Why are Map and MapCell in UI? They sound like part of the model. – Peter Taylor May 20 '11 at 12:42

I think the architectural pattern you're looking for is MVC. Currently it seems that World is all model but UI mixes model, view, and control.

  • That's very interesting, I will see if I can roll my own MVC around this. Fun! :) – Brian MacKay May 20 '11 at 14:43

I think what you are looking for is dependency injection. There is even a more decoupled way of doing DI and that is with a container (i.e. Dependency Injection Container or DIC for short).

  • I have looked into IoC containers and so on in the past. But I don't see how that will help me here... The problem I have is that my UI and World projects need to be able to interact with each other, but circular references are not allowed. Do IoC containers somehow get around that? Or am I missing something -- is the idea that I dump all my objects in a third project or something? Or put interfaces somewhere and just use those all over? – Brian MacKay May 20 '11 at 3:34

Why are you trying to separate out the world from participants?

By deriving the cell and participants from Entity, I am assuming you wanted a composite pattern for area effect actions. It is a pretty good application considering the scenario. Having said that, you could in theory have a base project with the entity class and the Map objects and have all the composite relationships setup in there. The child project can implement the creatures /actors etc. which can depend on the base project library - providing you a minor delineation. Also there are no circular dependencies necessary between the projects as long as you keep the reverse references in the Entity class itself. But without an indepth view into your whole project, it would be hard to advice an architectural change.

Some projects are inherently large - no point trying to split them up, unless you are ok with repetition of code etc. You should really evaluate what you will acheive out of this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.