I've found through doing some technical phone interviews, a lot of companies seek employees with "strong cs fundamentals". I'm not entirely sure what this means, but I know what kind of questions they ask--Oftentimes it's "write a function that implements quicksort" or "write a binary search tree delete". These can oftentimes be tough questions, especially if it's been some years since you've done those things. To me, what's more important is quality design and implementation of patterns. While quicksort and BST delete are important, they're oftentimes implemented in basic language/system libraries. It seems to me that the only way to build better/more complex algorithms is to know what the fundamental algorithms are, but more importantly, know how to use and build *on top* of them.
So, because I consider design perhaps a more valuable and rare skill, I'm going to begin a series of posts that examine (at an extremely high level) the idea of some basic design patterns in game programming.
Note: I suggest this book for good explanations of most basic design patterns. I also don't claim to be an expert, so feel free to correct me, and I'll try to update/fix my explanations as necessary.
First: The Factory Design Pattern
The Factory Pattern is a pretty basic pattern. It's when you abstract out a complex object's creation into a class method that generates members of that class. Take for example, the following pseudo-code from my game Total Toads (working title):
class Bug ...
class BugFalling implements Bug ...
class BugFirefly implements Bug ...
class BugMultiply implements Bug ...
In my game, you have frogs at the bottom who want to eat bugs who appear on screen in various ways. Each bug has a distinct look, and even bugs of the same type can have different properties. For example, some BugFalling are static and don't move, some are tutorial bugs, some move quickly, some don't animate, etc. Rather than having complicated and convoluted initialization processes, I can abstract these special properties out into my factory class, which I shall call "BugFactory". The header of BugFactory, given the desired types of bugs I just mentioned, might start to look like this:
// BugFactory creates bugs for specific uses
// BugFalling creation functions
static BugFalling bugFallingStatic();
static BugFalling bugFallingTutorial();
static BugFalling bugFallingAtSpeed(float speed);
static BugFalling bugFallingDontAnimate();
// Other bugs types might go below...
Notice that the BugFactory currently has 4 class methods that return an object of type BugFalling. Whereas before I had to create complicated constructor functions in the BugFalling class, now I have factored that out to having a single constructor, with additional configuration of the object done in the BugFactory. Now we examine one of the BugFactory functions, bugFallingStatic();
static BugFalling bugFallingStatic()
BugFalling bug = new BugFalling();
bug.speed = 0; // assume speed is a variable that controls the bug's fall
As you can see, this is a pretty basic function with a pretty basic purpose. You might imagine that in a more complex game with more complex objects, object creation can get a little crazy. Using a factory allows you to have a singular place in which to examine and modify your object creation. You can also imagine that extending BugFactory to create BugFirefly and BugMultiply objects would not be a huge endeavor (in fact, you should do this). And since they are similar objects (implementing the parent object type, Bug), having a factory makes it convenient and easy to modify their specific creation processes while making complex object instantiation just as easy and convenient.