Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Question regarding use of the Factory pattern


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 09:52 AM

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.


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!

Sponsor:

#2 Nanoha   Members   -  Reputation: 300

Like
2Likes
Like

Posted 18 May 2011 - 10:08 AM

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.

#3 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 10:13 AM

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?

Sounds reasonable about the abstraction level aswell, I'll see what way might be better to categorize the objects :)


Thanks a bunch for the reply!


#4 rip-off   Moderators   -  Reputation: 8762

Like
1Likes
Like

Posted 18 May 2011 - 10:33 AM

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.

#5 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 11:29 AM

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" ;)

#6 haegarr   Crossbones+   -  Reputation: 4601

Like
1Likes
Like

Posted 18 May 2011 - 11:50 AM

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.

#7 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 12:30 PM

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

#8 A Brain in a Vat   Members   -  Reputation: 313

Like
2Likes
Like

Posted 18 May 2011 - 12:46 PM

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();
}


#9 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 01:30 PM

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?)

#10 A Brain in a Vat   Members   -  Reputation: 313

Like
0Likes
Like

Posted 18 May 2011 - 01:50 PM

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.

#11 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 01:53 PM

Well actually I did edit my post the second you replied to add the fact that you could use it to force interfaces onto the client code, so polymorphism would be used as a clean way of working with the returned objects, if that was your point?

#12 A Brain in a Vat   Members   -  Reputation: 313

Like
1Likes
Like

Posted 18 May 2011 - 01:57 PM

Changed my mind. Read this: http://www.cs.qub.ac.uk/~P.Hanna/JavaProgramming/Lecture2/Java%20-%20Lecture%202%20-%20OOP%201.pdf

#13 A Brain in a Vat   Members   -  Reputation: 313

Like
0Likes
Like

Posted 18 May 2011 - 02:01 PM

Well actually I did edit my post the second you replied to add the fact that you could use it to force interfaces onto the client code, so polymorphism would be used as a clean way of working with the returned objects, if that was your point?


If you're asking: Do factories provide a clean way of allowing "client code" to have knowledge of only interfaces, then the answer is Yes.

Without a factory, the code would have to do:

void MyFunc(  )
{
        // MyFunc has to know what a DerivedObject is.. it has to include its include file, and it has no flexibility regarding whether it creates DerivedType or DerivedType2
        BaseObject * myObject = new DerivedObject();
}


#14 PastryCat   Members   -  Reputation: 100

Like
0Likes
Like

Posted 18 May 2011 - 02:06 PM

If you're asking: Do factories provide a clean way of allowing "client code" to have knowledge of only interfaces, then the answer is Yes.


Yeah that was the direction I was going for ^^ By doing that you're ensuring that you only ever work with abstractions of the concrete objects that gets created by the factories, without having to know certain details of how it needs to be initialized and so forth.




#15 LorenzoGatti   Crossbones+   -  Reputation: 2774

Like
0Likes
Like

Posted 26 May 2011 - 01:38 AM

Another important reason to use factories, which is likely to be relevant in a game, is ensuring coherence in covariant types that have expectations on the concrete types, and not only the public interface, of other objects created separately.
For example you could have a few interfaces to represent network stuff (Socket, Address, etc.) each with multiple implementations (e.g. IPv4 or IPv6). Trying to use an IPv6Socket with an IPv4Address would be an error: instead of creating concrete types like these directly and risking mismatches, you could rely on a NetworkStuffFactory (createSocket(), createAddress(), etc.) interface and choose in one place to use, say, a concrete Ipv6NetworkStuffFactory that creates compatible objects.
Produci, consuma, crepa




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS