C# Abstract Factory Pattern

C# Abstract Factory Pattern tutorial

Advertisements

Link To source Code

In previous post i introduced you to the concept of Factory Method. Abstract factory is very similar, but this time we will encapsulate all classes, by cremating interfaces for  Product and Factory. This pattern is also called as Factory of factories, because this patterns acts a superFactory which creates other factories. Abstract factory pattern in useful when the client needs to create objects which are somehow related, without specifying the concrete class.  With this pattern objects can interact with each other through common interfaces.

As usual I am using example from game development. In my example I’ll create Abstract Factory that will spawn enemies and give them specific weapon and armor.

UML diagram

l9

 

Factory

First thing to crate is the interface for Factory, that will be used to specify the equipment of each enemy.


 interface IEnemyFactory
    {
       IWeapon GetWeapon();
       IArmor GetArmor();
    }

Concrete classes will be named as the type of enemy that will be created. In my Example i have two enemies Mage and Warrior.


class Mage : IEnemyFactory
{
    public IWeapon GetWeapon()
    {
        return new Wand();
    }

    public IArmor GetArmor()
    {
        return new Cloak();
    }
}

class Warrior : IEnemyFactory
{
    public IWeapon GetWeapon()
    {
        return new Sword();
    }

    public IArmor GetArmor()
    {
        return new BodyArmor();
    }
}

Product

In next step we will create interface for items that will be given to the enemies. Both types share the same types of equipment, weapon and armor.


interface IWeapon
 {
     string Item();
 }
interface IArmor
 {
     string Item();
 }

In Concrete classes methods will return string values that will be printed to the console.


class Sword : IWeapon
 {
     public string Item()
     {
         return "Iron Sword";
     }
 }

class Wand : IWeapon
 {
     public string Item()
     {
          return "Magic Wand";
     }
 }
 class BodyArmor : IArmor
 {
      public string Item()
      {
          return "Iron Body Armor";
      }
 }

class Cloak : IArmor
 {
     public string Item()
     {
          return "Magic Cloak";
     }
 }

Client

Client is the last part is to create. Here we will create instance of the factory and spawn our enemies.


class Client
{

IEnemyFactory factory=null;

//SpawnEnemy method will decide what type of enemy will be created

//Based on string input

public void SpawnEnemy(string enemy)
 {
   if (enemy == "Warrior")
   {
     factory = new Warrior();
     Console.WriteLine("New Warior equipment:");
     Console.WriteLine(factory.GetWeapon().Item());
     Console.WriteLine(factory.GetArmor().Item());
     Console.WriteLine("_____________________");
   }
   else if (enemy == "Mage")
   {
     factory = new Mage();
     Console.WriteLine("New Mage equipment: ");
     Console.WriteLine(factory.GetWeapon().Item());
     Console.WriteLine(factory.GetArmor().Item());
     Console.WriteLine("_____________________");
   }
   else
   {
      Console.WriteLine("Wrong type");
   }
 }

 //Main method
 static void Main(string[] args)
 {
     Client client = new Client();
     client.SpawnEnemy("Mage");
     client.SpawnEnemy("Warrior");
     Console.Read();
 }
}

To conclude, Abstract Factory  provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is very useful but in large projects it may increase the complexity of the code. I hope you learned something new today. In next article You will learn how to implement another pattern. Stay Awesome!

 

C# Factory Pattern

C# Factory Pattern tutorial

This is one of the creational patterns. Factory is used to create an object from instance of another class.  In Factory pattern, we create object without exposing the creation logic. This helps to deal with large and more complex programs. In this pattern, an interface is used for creating an object, but let subclass decide which class to instantiate. Creation process is done in run time.

1245px-factory_1b-svg

I’ll use example from typical video game where Enemy object is created, and its type is based on random number. Object is created in run time.

 

 

 

 

UML diagram:

l3

 

First let’s create Interface that will be shared between all enemies that can be crated with Factory. This will be used by client.

public interface IFactory
{
  void Demage(int dmg);
}

 

Now we need to create Classes that will inherit this interface. In my example this will be enemyType1 and 2.

public class EnemyType1 : IFactory
{
  int _health=100;
  public void Demage(int dmg)
  {
     _health -= dmg;
     Console.WriteLine("EnemyType1 health:" + _health.ToString());
  }
}

public class EnemyType2 : IFactory
{
  int _health = 200;
  public void Demage(int dmg)
  {
     _health -= dmg;
     Console.WriteLine("EnemyType2 health:" + _health.ToString());
  }
}

Both classes also contains health count, just to make it more interesting.

Next we need to create the Interface for factory itself.

public abstract class EnemyFactory
{
  public abstract IFactory InstantiateEnemy(int type);
}

As a return type we use interface IFactory, this way we can return any object that inherits from it.

In The factory Class we override the method with switch statement that will return the objects based on the input number.

public class InstantiateEnemyFactory : EnemyFactory
{
  public override IFactory InstantiateEnemy(int type)
  {
     switch (type)
     {
        case 1:
            return new EnemyType1();
        case 2:
           return new EnemyType2();
         default:
           throw new ApplicationException(string.Format("Wrong number"));
     }
  }
}

 

Last step is to create client that will use the factory class.

class Program
{
  static void Main(string[] args)
  {
  //random number
  int type = new Random().Next(1, 1000)% 2 + 1;
  //Instance of the class
  EnemyFactory factory = new InstantiateEnemyFactory();

  IFactory newEnemy= factory.InstantiateEnemy(type);
  newEnemy.Demage(20);

  type = new Random().Next(1, 2000)%2 + 1;

  IFactory newEnemy2 = factory.InstantiateEnemy(type);
  newEnemy2.Demage(20);

  Console.ReadKey();

  }
}

Numbers don’t have to be random. I’m using random numbers to demonstrate the example. I real world we would rather create a list of enemies rather than choosing name for each of them.

This patters is very simple and effective. This makes it commonly used across all languages. To conclude, Factory defines an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. I hope you found it useful and you will implement this pattern to your next project. Stay Awesome!

Link to full source code