If you have read my previous blog about why we should use design patterns, you should already know how important they are. The design pattern I will be discussing is the simple factory and factory method patterns which belong to the creational design pattern category.
Simple Factory
This design pattern works by creating products from one "concrete" factory so that we don't have to use a new keyword whenever we want to create a certain object. The factory creates new products dynamically in the runtime without specifying what product to generate.
It solves a lot of problems by encapsulating product creation. We can dynamically create different products without knowing the concrete definitions. This reduces coupling in clients' code. The design for a simple factory is as follows:

Example of a Simple Factory
Let's see an example of how a simple factory works:
- First, we create an abstract product. In my example below, let's call it
IPlayer
. - Concrete products inherit from the abstract product. In my case,
Knight
,Mage
,GrandMage
,Lancer
inherits fromIPlayer
. - Next, we create a concrete factory
PlayerFactory
that creates different products according to the type provided. In my case, it creates thePlayerType
. - We now create new products from
PlayerFactory
rather than using new keywords everywhere.
The example using the pattern described is shown below.
using System;
namespace DesignPattern.Patterns.FactoryPattern.SimpleFactory
{
public interface IPlayer
{
void StartAttacking();
}
public class Knight : IPlayer
{
public void StartAttacking()
{
Console.WriteLine("Young knight is using his sword to slash enemies");
}
}
public class Mage : IPlayer
{
public void StartAttacking()
{
Console.WriteLine("Ice mage is using her ice attack to freeze enemies");
}
}
public class GrandMage : IPlayer
{
public void StartAttacking()
{
Console.WriteLine("I have mastered the power of fire");
}
}
public class Lancer : IPlayer
{
public void StartAttacking()
{
Console.WriteLine("I have very long spear");
}
}
}
namespace DesignPattern.Patterns.FactoryPattern.SimpleFactory
{
public static class PlayerFactory
{
public static IPlayer CreatePlayer(PlayerType playerType)
{
switch (playerType)
{
case PlayerType.Knight:
return new Knight();
case PlayerType.Mage:
return new Mage();
default:
return null;
}
}
}
public enum PlayerType
{
Knight , Mage
}
}
namespace DesignPattern.Patterns.FactoryPattern.SimpleFactory
{
public class SimpleFactoryDemo
{
public void Run()
{
IPlayer player = PlayerFactory.CreatePlayer(PlayerType.Mage);
player.StartAttacking();
player = PlayerFactory.CreatePlayer(PlayerType.Knight);
player.StartAttacking();
}
}
}
namespace Patterns
{
internal class Program
{
public static void Main(string[] args)
{
SimpleFactoryDemo simpleFactoryDemo = new SimpleFactoryDemo();
simpleFactoryDemo.Run();
}
}
}
// Above program outputs following
// Ice mage is using her ice attack to freeze enemies
// Young knight is using his sword to slash enemies
Factory Method
This design pattern works by creating products from a factory without defining what object type to create. The main difference between this pattern and a simple factory is that we create an abstract factory rather than a concrete implementation of the factory in this pattern.
The concrete factory will then override the creation process and creates a product with its own implementation. The client doesn't have to worry about the actual implementation of how products are created. The design for the Factory Method is as follows:

Example
Let's see an example of a factory method design implementation:
- Create an abstract product. In my example below, let's call it
IAbility
. - Make products inherited from
IAbility
. I have implementedFireAbility
,IceAbility
,SlashAbility
, andThrustAbility
. - Make an abstract factory. In my case, I'm using
IAbilityFactory
. This is where the factory method differs from the simple factory. Instead of the concrete implementation of a factory, we now depend onIAbilityFactory
. - Create concrete factories that implement
IAbilityFactory
. Here, these are calledElementalAbilityFactory
andPhysicalAbilityFactory
. - Now the client can just pass
abilityType
and get different products from different factories.
The example using the pattern described is shown below.
using System;
namespace DesignPattern.Patterns.FactoryPattern.Factory_Method
{
public interface IAbilityFactory
{
IAbility CreateAbility(AbilityType abilityType);
}
public class ElementalAbilityFactory : IAbilityFactory
{
public IAbility CreateAbility(AbilityType abilityType)
{
switch (abilityType)
{
case AbilityType.fire:
return new FireAbility();
case AbilityType.ice:
return new IceAbility();
default:
return null;
}
}
}
public class PhysicalAbilityFactory : IAbilityFactory
{
public IAbility CreateAbility(AbilityType abilityType)
{
switch (abilityType)
{
case AbilityType.slash:
return new SlashAbility();
case AbilityType.thrust:
return new ThrustAbility();
default:
return null;
}
}
}
}
namespace DesignPattern.Patterns.FactoryPattern.Factory_Method
{
public class FactoryMethodDemo
{
public void Run()
{
IAbilityFactory abilityFactory = new ElementalAbilityFactory();
IAbility ability = abilityFactory.CreateAbility(AbilityType.fire);
ability.UseAbility();
ability = abilityFactory.CreateAbility(AbilityType.ice);
ability.UseAbility();
abilityFactory = new PhysicalAbilityFactory();
ability = abilityFactory.CreateAbility(AbilityType.thrust);
ability.UseAbility();
ability = abilityFactory.CreateAbility(AbilityType.slash);
ability.UseAbility();
}
}
}
using System;
namespace DesignPattern.Patterns.FactoryPattern.Factory_Method
{
public interface IAbility
{
void UseAbility();
}
public enum AbilityType
{
fire , ice, slash , thrust
}
public class IceAbility :IAbility
{
public void UseAbility()
{
Console.WriteLine("Ice ability used");
}
}
public class FireAbility :IAbility
{
public void UseAbility()
{
Console.WriteLine("Fire ability used");
}
}
public class SlashAbility :IAbility
{
public void UseAbility()
{
Console.WriteLine("slash attack used");
}
}
public class ThrustAbility : IAbility
{
public void UseAbility()
{
Console.WriteLine("thrust attack used");
}
}
}
namespace Patterns
{
internal class Program
{
public static void Main(string[] args)
{
FactoryMethodDemo factoryMethodDemo = new FactoryMethodDemo();
factoryMethodDemo.Run();
}
}
}
// Above program outputs following
// Fire ability used
// Ice ability used
// thrust attack used
// slash attack used
Abstract Factory
This design pattern works by creating multiple products that belong to the same families using a factory. A single factory is responsible for creating families of the related object without specifying their concrete subclass. One factory should produce at least 2 products that are somehow related to each other. The Design diagram for the abstract factory is shown below.

Example
Let's see an example of a factory method design implementation:
- We need to first create at least 2 abstract products that are somehow connected. In my case, they are
IPlayer
andIAbility
. - We then create new concrete products from
IPlayer
andIAbility
. I havefire
,ice
,slash
, andthrust
that inherit fromIAbility
, andMage
,GrandMage
,Knight
,Lancer
that inherit fromIPlayer
. - Since abstract factory deals with families of objects, it needs to be able to create at least 2 products. In my case, it creates
player
andability
. - We need to make a concrete implementation of the factory. I have
MagicClassFactory
andMeleeClassFactory
that inherits fromICharacterClassFactory
. - Finally, we create ability and player by passing
abilityType
as a parameter when creating these products.
The example using the pattern described is shown below.
using System;
using DesignPattern.Patterns.FactoryPattern.Factory_Method;
using DesignPattern.Patterns.FactoryPattern.SimpleFactory;
namespace DesignPattern.Patterns.FactoryPattern.Abstract_Factory
{
public interface ICharacterClassFactory
{
IPlayer CreatePlayer(AbilityType type);
IAbility CreateAbility(AbilityType type);
}
public class MagicClassFactory : ICharacterClassFactory
{
public IPlayer CreatePlayer(AbilityType ability)
{
switch (ability)
{
case AbilityType.ice:
return new Mage();
case AbilityType.fire:
return new GrandMage();
default:
return null;
}
}
public IAbility CreateAbility(AbilityType abilityType)
{
switch (abilityType)
{
case AbilityType.fire:
return new FireAbility();
case AbilityType.ice:
return new IceAbility();
default:
return null;
}
}
}
public class MeleeClassFactory : ICharacterClassFactory
{
public IPlayer CreatePlayer(AbilityType ability)
{
switch (ability)
{
case AbilityType.slash:
return new Knight();
case AbilityType.thrust:
return new Lancer();
default:
return null;
}
}
public IAbility CreateAbility(AbilityType abilityType)
{
switch (abilityType)
{
case AbilityType.slash:
return new SlashAbility();
case AbilityType.thrust:
return new ThrustAbility();
default:
return null;
}
}
}
}
using DesignPattern.Patterns.FactoryPattern.Factory_Method;
using DesignPattern.Patterns.FactoryPattern.SimpleFactory;
namespace DesignPattern.Patterns.FactoryPattern.Abstract_Factory
{
public class AbstractFactoryDemo
{
public void Run()
{
ICharacterClassFactory characterClassFactory = new MeleeClassFactory();
IPlayer player = null;
IAbility ability = null;
player = characterClassFactory.CreatePlayer(AbilityType.thrust);
ability = characterClassFactory.CreateAbility(AbilityType.thrust);
player.StartAttacking();
ability.UseAbility();
player = characterClassFactory.CreatePlayer(AbilityType.slash);
ability = characterClassFactory.CreateAbility(AbilityType.slash);
player.StartAttacking();
ability.UseAbility();
characterClassFactory = new MagicClassFactory();
player =characterClassFactory.CreatePlayer(AbilityType.fire);
ability = characterClassFactory.CreateAbility(AbilityType.fire);
player.StartAttacking();
ability.UseAbility();
player = characterClassFactory.CreatePlayer(AbilityType.ice);
ability = characterClassFactory.CreateAbility(AbilityType.ice);
player.StartAttacking();
ability.UseAbility();
}
}
}
namespace Patterns
{
internal class Program
{
public static void Main(string[] args)
{
AbstractFactoryDemo abstractFactoryDemo = new AbstractFactoryDemo();
abstractFactoryDemo.Run();
}
}
}
// Above program outputs following
// I have very long spear
// thrust attack used
// Young knight is using his sword to slash enemies
// slash attack used
// I have mastered the power of fire
// Fire ability used
// Ice mage is using her ice attack to freeze enemies
// Ice ability used
All the above patterns are categorized under creation patterns. These design patterns deal with creating objects.
Hope you learned something new from this. I will be coming up with more design patterns soon.