I have a problem that involves a relatively large object hierarchy as follows:
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:
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.
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?
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 :
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... ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With