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
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!