Tag Archives: mario

The Factory Pattern

In part II of our programming mini-series we’ll dive into the Factory Pattern, how it can be used, and when it can be beneficial.

The Factory Pattern itself is fairly straight forward. When we use the Factory Pattern we are building a Factory that will produce objects for us. There’s two key reasons this pattern is helpful and I’ll share some examples of how we can use it.

First and foremost, the Factory Pattern allows us to encapsulate (wrap and hide) the creation of objects. This means that instead of coding ourselves into a maintenance nightmare where we are instantiating concrete class after concrete class, we can instead code to a single factory and allow it to provide our instantiation. Let’s look at a bad example:

public class LevelOne
{
	public void CreateEnemy(string enemyName)
	{
	   if (enemyName == "HammerBro")
		  HammerBro hammerBro = new HammerBro();
	   else if (enemyName == "BulletBill")
		  BulletBill bulletBill = new BulletBill();
	   else if (enemyName == "PiranhaPlant")
		  PiranhaPlant piranhaPlant = new PiranhaPlant();
	   else if (enemyName == "KoopaTroopa")
		  KoopaTroopa koopaTroopa = new KoopaTroopa();
	   else if (enemyName == "Goomba")
		  Goomba goomba = new Goomba();
	}
}

What you see above is pretty common in Software Development. We need a function that we can tell what kind of enemy we need and it will create it for us. However, this approach comes with a lot of headaches.

Any time we want to add a new enemy we now have to open this class back up and make a change. Anytime we have to make a change to existing code, we’re introducing risk. Now, we’ll have to change this code no matter what if we want to add a new enemy BUT we can do this in a way that reduces our risk and the number of changes we have to make in our application.

Consider that instead our class is used by another development team. Now each time we add a new enemy we have to ask that team to update their create function to be compatible with ours. Now consider this other team is actually a customer or vendor. How easy is it to ask them to make changes every time we make a change?

And let’s say we want this function that creates our enemy to return our enemy so he can do things like attack. We’ll we’re going to need a lot of code and a lot more if statements to do things like:

if (koopaTroopa)
   koopaTroopa.Attack();
else if (goomba)
   goomba.Attack();

The Factory Pattern makes this all go away. It does away with the dependencies on concrete classes, it abstracts the creation of enemies, and it reduces the amount of code that needs changed when new Enemy class are created or changed.

The second benefit we’ll get from our Factory is a centralized place for anyone to get an enemy from. This means that on Level 1 we can use the same factory to create the same enemies as we use on Level 20. We don’t need to re-implement enemy instantiation or repeat any of our enemy code. Woot!

So what can our Factory look like? Well with the help of an Interface it can look like this:

public class EnemyFactory
{
	public IEnemy CreateEnemy(string enemyName)
	{
	   if (enemyName == "HammerBro")
		  return new HammerBro();
	   else if (enemyName == "BulletBill")
		  return new BulletBill();
	   else if (enemyName == "PiranhaPlant")
		  return new PiranhaPlant();
	   else if (enemyName == "KoopaTroopa")
		  return new KoopaTroopa();
	   else if (enemyName == "Goomba")
		  return new Goomba();
	}
}

Now you might say, wait a minute… this looks exactly the same as what we had before. And you’d be right! It’s very close, so let’s take a look at what’s different.

Instead of instantiating the enemy and storing a copy of the concrete class within LevelOne we have abstracted the creation to another class (our Factory!). We’ve also implemented an Interface, think of an interface like wrapping paper around our object, it will allow us to treat the enemy in a generic way. Our interface might look like this:

public interface IEnemy
{
   public void Attack();
}

With our new Factory and Interface we can now flexibly create the enemies we need, have them attack (and perform the correct attack), and our friends on the other development team will love us so much more because they no longer need to refactor and write new code each time a new enemy class is created. Let’s see an example:

public class LevelOne
{
   IEnemy currentEnemy;//our enemy to fight
   
   public LevelOne()
   {
      //create our factory
      EnemyFactory factory = new EnemyFactory();	  
   }
   
   public void CreateGoomba()
   {
      //let our factory create the enemy
      currentEnemy = factory.CreateEnemy("Goomba");
   }
   
   public void AttackPlayer()
   {
      //our interface knows which enenmy Attack() function to call
      enemy.Attack();
   }
}

So what’s so different and special about this design? Well for one, our LevelOne class no longer depends on 6 other enemy classes. If our game designer comes along and decides that, “Oh we want to create a new Goomba class called SuperGoomba” we can now easily make that change on one line of code.

What else is helpful here? Well now we have a single place to go to for enemy creation. Not only can LevelOne create any enemy it wants, so can LevelTwo, and LevelTen, and so on. And if new enemies are added, none of the code needs to change for existing levels.

The final benefit we gain from using the Factory Pattern is the advantage of using interfaces. By allowing our Factory to return an interface instead of a concrete class we can make it much easier for other developers to use our factory. Developers won’t need to code for 6 different Attack() functions for each enemy type. They can instead code a single ‘enemy.Attack()’ function which will allow us to call each enemies Attack() without actually having to know which enemy it is.

In closing, the Factory Pattern is simply a way for us to create a Factory that does all the hard work of creating objects and gives them back to us in a generic fashion by using an Interface. It allows us to decouple our code, encapsulate instantiation, and provide highly maintainable solutions. If you find that you’re using the ‘new’ keyword to create objects it might be a good time to consider using the Factory Pattern.