[C# Design Patterns] The Factory Pattern

One of the practices I want to use in my Precise Programming is to instantiate all objects through factories.

This will add a little more complexity, because it is another class I’ll need to create. However, I believe the benefits it adds (through additional flexibility) will outweigh the cost of creating the new class.

 

If you prefer a video, you can watch this lesson here:

 

What is the factory pattern?

The factory design pattern is a different way to instantiate objects.

Instead of creating a new object by calling the class constructor, you call another function (the “factory”) that constructs the object.

 

Why would you use a factory to instantiate objects?

An object factory can help if you ever need to change the way you construct your objects.

You might need to do this if your objects use classes from another library. The other library may change its behavior, or requirements, when you upgrade to a newer version.

You may also want to do something new with the objects – log that they were created, use them in a queue, attach eventhandlers to them, etc.

With a factory, you might be able to make the change once (inside the factory method) instead of making it several places (every other place in your project that would have instantiated the object).

 

For these examples, we will create a Player object for a role-playing game.

 

Code sample (before, without a factory)

Player.cs

With this technique, every place we want to create a new Player object, we would write code like this:

 

Code sample (with factory inside the business object class)

One way to create a factory is to add a static method to the class we want to instantiate.

We can call this static method without an instance of the object. It will create a new instance of the Player class, and return it to the calling code.

We’ll also change the scope of the class constructor to “private”, so it can only be called by other methods in the Player class. Now, no other part of our program can call the constructor. They must use the factory method.

 

Player.cs

Now, we create a Player object in the rest of our program by calling the factory method:

 

This is a factory method, but it doesn’t help us out very much. Not much has changed. We still call a method on the business object, and it returns a new Player object.

So, let’s see what happens with a more useful example – when you have a separate factory class, to create a player object from saved game data.

 

Code sample (with a separate factory class)

We need to change the scope of the Player class constructor to “internal”, from “private”, since we will call the constructor from a different class (our factory class) that is still in the same assembly/project. So now, it looks like this:

 

Player.cs

 

We’ll create a new class that will be a factory to (eventually) create Player objects from wherever we store the saved game data. For this first version, we won’t look for saved data.

 

PlayerFactory.cs

Now, when we want to create a new Player object, our code would look like this:

 

Next, we’ll expand the factory to load the player data from an XML file.

 

PlayerFactory.cs

 

When we want to load a Player object, our calling code does not need to change. It still looks like this:

 

If we decide to read saved game data from a SQL database, or from the Internet, or any other place, we only need to change the internals of the LoadPlayer method. The calling code always stays the same.

That’s where the factory method is very helpful. It allows us to make the change in one place, and not require that we make changes in several different places in our program.

 

Another way we can use an object factory

You can also use a factory method if you want to create objects that are different types – as long as they have the same base class, or implement the same interface.

In this situation, the return type of your factory method would be the base class, or the interface.

 

For example, let’s say we want to create monsters for our game. We have a base Monster class, with child classes of FlyingMonster, LandMonster, and SeaMonster.

 

Here are very simple versions of our monster classes:

 

Monster.cs

FlyingMonster.cs

LandMonster.cs

SeaMonster.cs

When we want a monster, let’s call our MonsterFactory, have it get a random number, and return a monster.

 

MonsterFactory.cs

When we want a monster, we can call this code:

 

If we expand our game, to have more types of monsters, we only need to make the change in the GetRandomMonster() method – not the rest of our program.

 

Real-world example where the factory design pattern helped me

I once worked on a project that translated work requests between multiples programs. A work request would be submitted to our program, it would determine what format the request was in, where it needed to be sent, and what format was needed for the program it was being sent to.

Once the program knew the two formats, it would instantiate a translator object that knew how to do the conversion between those two formats.

When the conversion was done, the convertor objects should have released their memory. However, they had a bug, and held on to the memory they were using. After we did a few thousand conversions, our program would crash.

Fortunately, we were creating the convertor objects with a factory.

So, all I had to do was go into the factory class and change the code to re-use convertor objects, instead of constantly creating new ones. After that change, there would only ever be one of each type of convertor object – which didn’t take up much memory.

Leave a Reply

Your email address will not be published. Required fields are marked *