Question regarding use of the Factory pattern

Started by
13 comments, last by LorenzoGatti 12 years, 11 months ago
[font="arial, verdana, tahoma, sans-serif"]Hello everyone :)

I'm currently on my way to finish first year of my computer science education, and just a while ago we were introduced to design patterns, namely the more simple ones as the famous singleton pattern, as well as the different sorts of the factory pattern as starters.[/font]

Now it seems that most of my professors have quite a different idea of their definition and practical use of the factory pattern. I've been researching a bit around the internet and I am now officially lost in what actual practical use it has, what's the real meat of the pattern?

The two current core ideas I've been explained are as follows:
1) Provide a general interface for all objects (especially counts toward the method factory as I understand it? Since you're able to hide the actual implementation and just return an interface type the client code can use).
2) Remove initialization logic from the client code (things like parameters and the like), to collect all this logic in one unit so it's easier to quickly make changes should your classes suddenly require additional parameters (instead of having to jump around in 10 different classes in the client code initializing the same object to add the newly introduced parameters.

Now for a current project we're doing, me and my group have tried implementing the factory pattern as a part of our core design. But we've quickly run into a couple of design related questions, and they're kinda big! First of all, how are you supposed to handle parameters if you need to provide this when using the factory? For example, we have a UIElement factory from where we want to initialize things like menu buttons and so on, but the menu button class constructor requires a screen position, as well as what game state to change to upon click and so on. It seems impossible to be able to do this through a factory without providing a parameter array to the factory create method, but this approach would seem to contradict the second reason I mentioned above, thus defeating the purpose of the pattern in the first place. On various other sites on the other hand, they say using parameters with a factory is perfectly okay, although I also personally think providing this parameter array isn't really good design as the client code will have to know exactly what objects require what set of parameters, which actually also contradicts the first idea I mentioned. What is the best approach to doing this?

Also, how literal are you supposed to take the general interface part? In our current design we have factories to create UIElements, game objects, screen objects and so forth, and they all return an interface type of the name IUpdateable (which is just an update and draw method), is it generally a good idea to try and use that much abstraction? Also as a note, the client code do not have access to these sub-factories, but they all call a FactoryManager which will check each factory for the object type the client code called the method with, see which one can create it, and then call the CreateObject method from that factory.

Well, I think that was about it :) My head is actually very confused right now regarding these things, and I've seen to become stuck, not knowing in which direction to move. I hope there's some experienced software engineers out there willing to lend a hand :)

Thank you all for your time, any help is really appriciated!
Advertisement
If an object needs parameters then it need parameters, no other way about it. So I wouldn't worry about that. I'm currently using a factory to create component based entities ({So they are all of a "Entity" type but can be quite different in what they do). Its working out really well, I don't have the parameter problem (as I'm loadingg from xml files) but it does neatly wrap up all the "assembley".

As far as your design goes, I think your being far too general (So many things are all IUpdatable), when you have such general (and losely related) thing then you can't really make a useful interface. UiObjects (buttons, text boxes etc) are all well related so it might be a good idea to make a common interface for those. Game objects might be another usefull group of objects.

Make sure you do actually need a factory, if all your methods are doing is creating and returnig a new object then I wouldn't use one. If its doing more (say creating a button element, adding it to some parent and possitioning it then forcing an update) then its probably a good candidate. Other things like loading from a file could be wrapped up in a factory, that way you move all the file stuff out of the objects themself.

I'd avoid having one huge "Factory Manager" that does it all.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

[color="#1c2837"]Aaaah interesting, so essentially a factory only really becomes useful when there is additionally logic related to the initialization of an object? That is, you actually need to do more than simply doing an initialization with "new myType"... etc?
[color="#1c2837"]
Sounds reasonable about the abstraction level aswell, I'll see what way might be better to categorize the objects :)
[color="#1c2837"]
Thanks a bunch for the reply!
Factories are good for hiding common parameters. For instance, if you want a factory for game objects, you might have to pass parameters indicating the type of object to create (maybe a string) and the position to create it at. But the factory can hide some additional parameters, for example passing a reference to the GameWorld object, or references to ContentLoader objects.

So when your Necromancer tries to summon a Skeleton, the Necromancer doesn't need to worry about providing references to these high level objects, as they are provided by the factory.

Don't try to force patterns where they aren't necessary. Just because you are creating objects does not imply you need a factory. However, if you find you have a function in some class whose purpose appears to be figuring out which concrete class to instantiate, then "promoting" this function to a factory can sometimes improve your design and reduce coupling. If you aren't data driven you probably don't need a factory. Then again, if you aren't data driven maybe you should strive to be =]

Patterns are a tool for refining a design, not for creating one in the first place.
Now I just got a much clearer idea of when a factory pattern should be applied, thank you all very much :)

And rip-off, I especially took good notice of the last line in your post ^^ Puts things into a much better perspective, as I think we've actually tried to implement our design around the potential use of the factory pattern, and as it is right now it actually does look quite pointless for our current design. Time to refine it, hopefully the end product will be much better :) I'm pretty certain this has been a case of "design fever" ;)

[color="#1c2837"]Aaaah interesting, so essentially a factory only really becomes useful when there is additionally logic related to the initialization of an object? That is, you actually need to do more than simply doing an initialization with "new myType"... etc?

A factory may also be well suited when it only contains a "return new MyClass();" line of code. This is the case when you need to hide the concrete type MyClass, or the client can/need/shall not know it. E.g. a graphics sub-system provides a factory method for off-screen graphics rendering targets. OpenGL as a concrete type of graphics sub.system needs to deal with other rendering targets than D3D, for example. But the client should work without knowledge what concrete sub-system is in use. So a pure virtual factory method is declared in the base class of the sub-system, and it is implemented in the concrete sub-types one time returning a OpenGL suitable render target (by the OpenGL sub-system, of course) and the other time returning one suitable for D3D (by the D3D sub-system, of course).

My usage of pattern is as follows: If I hit a problem, and the problem more-or-less matches one for which I know a pattern, I use the pattern (perhaps with slight modifications) to solve the problem. There is no need to search for places where to apply patterns. Just know what patterns can be used to solve what kind of problem.
So in that case you would pretty much use factories when the client doesn't actually need to know anything about the specific implementation of a sub-system, it just needs to be able to call the same general methods without caring about how that's actually done for each sub-system?

Also, would it then be appropriate to have several types of factories returning different types of base classes, obviously following that the way they need to be created is a relevant problem for the factory pattern? For example in one project, have a factory which returns UIElements, a factory which returns game objects, and so on? Seeing as they might have very different implementations and the client code handling each type would probably need to know specific general things, but for each category.

And yeah, the usage of patterns by simply using it with your design when a relevant problem occurs seems so obvious, but I've been clouded a bit these last couple of days :D

So in that case you would pretty much use factories when the client doesn't actually need to know anything about the specific implementation of a sub-system, it just needs to be able to call the same general methods without caring about how that's actually done for each sub-system?


What you've just described is one of the important bases of Object Oriented Programming.


Factories become useful when you want code to be able to create objects without knowing what it's creating or how to create it. For example:


// objects
class BaseObject {};
class DerivedObject : public BaseObject {};

// factories
class BaseFactory
{
virtual BaseObject* CreateObject() = 0;
}
class DerivedFactory : public BaseFactory
{
virtual BaseObject* CreateObject()
{
// create the new object
DerivedObject* newObj = new DerivedObject();

// do a bunch of initialization stuff
newObj->Initialize(blahblahblah);

// return the new object as a base class pointer
return newObj;
}
}


void MyFunc( const BaseFactory& factory )
{
// I don't know that myObject might actually be of type DerivedObject, nor do I care
BaseObject * myObject = factory.CreateObject();
}
I think maybe in those kind of situations, the problem is I don't really have enough experience to be able to see when you would actually need code that's pretty much completely careless of anything that gets made or returned? In what relations you would actually have a use for that? (other than maybe again as I said, forcing an interface to the client code so it uses polymorphism for whatever it needs to hide the concrete type of?)

I think maybe in those kind of situations, the problem is I don't really have enough experience to be able to see when you would actually need code that's pretty much completely careless of anything that gets made or returned? In what relations you would actually have a use for that?


Sounds like you've been learning C++ but not Object Oriented Programming. That's okay, to a point, depending on your purposes, but if you're going to be reading about factory patterns then you really need to learn about OO and understand its motivations.

There's information all over the internet about OO, so I won't bother pointing you to some, just search and learn. The reason I'm suggesting this is that every C++ programmer should be able to answer the very question you just asked. Some might say the whole point of C++ is to do exactly that: use code without knowing anything about it. The word for that is Abstraction. You really need to learn about it and the other OO concepts before you learn about design patterns because the vast majority of them are OO design patterns.

This topic is closed to new replies.

Advertisement