Skip to main content
GameDev.net gamedev.net
🔒 Locked

Explain the Factory Pattern.

Started by Shakedown Feb 25, 2008 at 8:13 PM 3 replies 2.8k views
Original Post
Shakedown
Shakedown
Ok. I've got both the GoF pattern book and Head First Design Patterns in front of me, but I'm having trouble fully understanding any of the Factory Patterns (Factory, Abstract Factory, Factory Method). Currently I'm working on a space invaders type space shooter. The main Entity in my game is <>Ship, which has 2 subclasses: PlayerShip and <>EnemyShip. Now the EnemyShip has several subclasses, all of which are the individual types of enemies (i.e. AggressiveEnemy, DefensiveEnemy, KamikazeEnemy, etc). Also, everything is hard-coded, there's no XML or file loading/reading going on. So, ignoring any knowledge of the Factory Pattern/s, I would imagine that I could have a Factory to produce my EnemyShips. Now, taking the patterns in account, I can't figure out how I could use a Factory for my ships. From what I understand, when a call is made to the Factory to produce an EnemyShip, the Factory needs to know what EnemyShip to produce. Here's where the pattern loses me. If the Factory needs to know what to produce, what's the point in delegating the task of creating that specific EnemyShip to the Factory, when you could just explicitly create a new EnemyShip of that specific type?
stonemetal
stonemetal
There is knowing and there is being able to specify.

I can have code that knows about the general enemy class, and is told to ask for a certain type of enemy. That code doesn't know anything about the type of enemy it is about to create, but it is able to specify the type of enemy is going to get.
Say latter on you have levels out in a file, nothing but the factory and the level file needs to know that the specific enemy types exist.
Ravyne
Ravyne
The factory pattern allows you to specify which object is to be created through the use of a "token." This token might be an integer ID such as an enum Value or a string containing the human-readable name of the object, it might be anything at all.

This is useful because it means that the requester only needs to know the token, rather than the specifics of the requested object itself. An example use is that a level file might contain integer tokens to specify what enemy ships are to be created. The level file parser does not, and should not, need to know the specifics of any of the ships, because it does not need to interact with them in any way beyond creating them -- hence, it asks the factory to produce them for them.

The factory pattern is very much like a real factory -- clients place an order for what they want, and don't care about how they're built or work as long as they meet the order. Only the factory needs to know how to produce the object. This is good because it limits the number of parties who know about the internals of the object, and hence reduces dependencies.
throw table_exception("(? ???)? ? ???");
speciesUnknown
speciesUnknown
To my understanding, there is also the fact that you can put the details of construction elsewhere and have the "factory" class or functions load that location, rather than having to hard code the resource loading system, or have each object construct itself.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Neon2302
Neon2302
Factory always must have clue about what object are going to create

Factory Patterns use to allow client don't need to know what object (and how many type) of object are going to create


a = factory.create(...clue about which one are going to create...)

this is useful when you need to add more type of object (such as more enemy ship types) so you don't need to modify any of client, just modify factory one place.

the example is

class Stage1
EnemyShip eShip1 = EnemyShipFactory.create(EnemyShipFactory::AGGRESSIVE_ENEMY);
EnemyShip eShip2 = EnemyShipFactory.create(EnemyShipFactory::DEFENSIVEE_ENEMY);

class Stage2
EnemyShip eShip1 = EnemyShipFactory.create(EnemyShipFactory::DEFENSIVEE_ENEMY);
EnemyShip eShip2 = EnemyShipFactory.create(EnemyShipFactory::KAMIKAZE_ENEMY);

when you add new kind of enemey you don't need to change any of Stage1 or Stage2 class just change the value passing to Factory

you will see the advantage when you parse the data from the file you just change the datae in files and EnemyShipFactory class and eveythings done.

Best Regards,
Chet Chetchaiyan

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.