Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern to build a large hierarchy of objects

I have a problem that involves a relatively large object hierarchy as follows:

  • game has one community manager
  • community manager has one network
  • network has many players
  • network has many friendships
  • player has one strategy manager
  • player has one memory
  • player has one neighbourhood
  • neighbourhood has many players
  • strategy manager has many strategies

As you can see, the hierarchy is relatively complex and in at least one place cyclic (network has many agents having one neighbourhood which has one network). At the moment I am using a static construct method on a GameFactory class to construct the whole hierarchy but I'm pretty sure this is the least flexible way of doing it!

In terms of building a complex hierarchy of objects what is the best pattern to use? I've read up on the Factory Method, Abstract Factory and Builder patterns and I think one of the factory patterns is suitable but I don't really know how to apply it to such a complex hierarchy?

As I see it I'll need many factories for each part of the system but this will result in a collection of factory classes mirroring the model classes.


Edit: It has become clear from the discussion in suggestions given so far that I should have explained more about why I require factories to build my object hierarchies rather than allowing constructors themselves to build their dependencies.

This is because I am using dependency injection to aid in test driven development. I'm taking a mockist approach to the testing which requires the ability to inject mocks representing an object's dependencies and as such I have to avoid using new in any constructors.

From the suggestions given so far it seems there are a number of possible ways of doing this:

  • Create a secondary constructor in each class that builds any dependencies required by the object being constructed. This allows dependency injection and simple object hierarchy construction.
  • Have a factory class (either a single one or a hierarchy of them depending on the type of factory pattern used) mapping to each domain class to deal with its construction.
  • Use a combination of these methods where factory classes are only created when there is something that varies in the construction process (i.e., different subclasses need to be constructed under certain circumstances)

I am inclined to take the last route. What is the consensus on the best approach to take in this situation?


Edit: I'm revoking the current answer (the one by Patrick Karcher) since now that this question's focus has been clarified, none of the suggestions are complete answers.

like image 215
tobyclemson Avatar asked Jan 25 '10 14:01

tobyclemson


2 Answers

It's important to understand why exactly you need a factory. As with a lot of "good" practices, a factory can yield certain advantages, which you sometimes want, and which you get only by using them properly.

Often the factory is another class in your object model. For example, you'll often end up with a player because you have a neighborhood with a players collection and you'll iterating through it, doing stuff to the players. Or you're starting with a network object. Or (I'm guessing) you already have a player from it you get a friendship and you get the player from it. So a friendship is factory for player objects and a player is factory for friendship objects!

You do though sometimes have reason for non-domain, dedicated factory objects. You might have a factory class as a starting point for objects that you'll begin your logic with. Often they're used when there are a lot of tricky ways some of your objects need to be instantiated and the factory is a good way to organize them. Sometimes your objects need to get instantiated with, for example, a data layer and a user and a context, and a factory can maintain those things, make your objects, and save you from having to repeat yourself in a lot of different constructors. Sometimes the factory can automatically generate common references that your various tools need.

There is one use of a factory that is growing rapidly in popularity, and deserves special mention. This is the use of a factory class to add a layer of misdirection to inject dependencies, particularly for unit testing.

My advice is if you don't have a specific reason to use a factory object in mind, don't worry about them. Just build your objects with good constructors. Then it will be natural to add properties that return related objects; these will be your first factories. This might be a good example of how you don't want to worry about design patterns at first; design patterns do not deliver success. You do. Patterns, like the various factory patterns, can help but must not replace basic object-oriented thinking.

Do you have specific reasons in mind for why you need dedicated factory objects?

like image 84
Patrick Karcher Avatar answered Sep 28 '22 00:09

Patrick Karcher


If nothing varies, ie. if your construction process is fixed, I would recommend the simplest way : have the objects themselves take care of building their dependent objects, and establishing links (potentially bi-directional).

Example : For a parent object with a collection of children, the parent can have a addChild method that ensure the coherence of the bi-directional relationship :

  1. get the previous parent of the child ; if not null, remove the child from that old parent.
  2. change the parent field in the child to the new parent
  3. add the child to the collection of children of the new parent.

If something varies, like subclasses than should be used in some context, then you have to define exactly what varies. Only after you found your precise need, the correct patterns may appear. :-)

We could help with the last part, but you are the only one that can give the required information... ;-)

like image 44
KLE Avatar answered Sep 28 '22 00:09

KLE