In my previous article I explained about what is design pattern, advantages of design patterns and also about factory design pattern, when we have to use factory design patter.
In this article we discuss about abstract design pattern and its usage. Abstract factory design pattern is extension of factory design pattern. Abstract factory is nothing but grouping of related or dependent objects. It groups the products that are exist in families and are designed to produce together.
Abstract factory provides the interface to access family of related objects without specifying their concrete classes. That means if you want to access one instance of multiple related classes, abstract factory provides that instance. In abstract factory design pattern, we are hiding the client from knowing which class it is accessing from group of related classes.
In my previous example I took the Banking example to explain the factory design pattern. Here also I am taking same example, but with some extra functionality by taking options available from banks to pay the amount and we are hiding actual classes which are providing the pay option details from bank.
Abstract Factory pattern contains several players and divided into four.
AbstractFactory
- An Interface and a class with create options for each of the abstract products
Factory 1, Factory 2
- Implementation of all abstract factory creation patterns
AbstractProduct
- An interface for a kind of products with its own operations
ProductA1, ProductA2, ProductB1, ProductB2
- Classes that implement the AbstractProduct interface and define product objects to be created by the corresponding factories
Client
- A class that access only AbstractFactory and AbstractProduct players.
In our banking example, we created all these players, below are the corresponding component for each player.
AbstractFactory - IPay interface and BankFactory class
Factory 1, Factory 2 - BankA and BankB classes
AbstractProduct - ICreditCard and IDebitCard interfaces
ProductA1, ProductA2, ProductB1, ProductB2 - BankACreditCard, BankADebitCard, BankBCreditCard, BankBDebitCard
Client - Program.cs class
Implementation of each player is as shown below.
AbstractFactory – IPay interface
namespace AbstractFactoryDesignPattern
{
interface IPay
{
ICreditCard GetCreditCardDetails();
IDebitCard GetDebitCardDetails();
}
}
namespace AbstractFactoryDesignPattern
{
class BankFactory
{
public IPay PayOption(string bankName)
{
bankName = bankName.ToUpper();
if (bankName == "A")
return new BankA();
else
return new BankB();
}
}
}
Factory 1, Factory 2 - BankA and BankB classes
namespace AbstractFactoryDesignPattern
{
class BankA:IPay
{
#region IPay Members
public ICreditCard GetCreditCardDetails()
{
return new BankACreditCard();
}
public IDebitCard GetDebitCardDetails()
{
return new BankADebitCard();
}
#endregion
}
}
namespace AbstractFactoryDesignPattern
{
class BankB:IPay
{
#region IPay Members
public ICreditCard GetCreditCardDetails()
{
return new BankBCreditCard();
}
public IDebitCard GetDebitCardDetails()
{
return new BankBDebitCard();
}
#endregion
}
}
AbstractProduct - ICreditCard and IDebitCard interfaces
namespace AbstractFactoryDesignPattern
{
interface ICreditCard
{
string PayFromCreditCard();
}
}
namespace AbstractFactoryDesignPattern
{
interface IDebitCard
{
string PayFromDebitCard();
}
}
ProductA1, ProductA2, ProductB1, ProductB2 - BankACreditCard, BankADebitCard, BankBCreditCard, BankBDebitCard
namespace AbstractFactoryDesignPattern
{
class BankACreditCard:ICreditCard
{
#region ICreditCard Members
public string PayFromCreditCard()
{
return "Pay through Credit Card From Bank A";
}
#endregion
}
}
namespace AbstractFactoryDesignPattern
{
class BankADebitCard:IDebitCard
{
#region IDebitCard Members
public string PayFromDebitCard()
{
return "Pay through Debit Card From Bank A";
}
#endregion
}
}
namespace AbstractFactoryDesignPattern
{
class BankBCreditCard:ICreditCard
{
#region ICreditCard Members
public string PayFromCreditCard()
{
return "Pay through Credit Card From Bank B";
}
#endregion
}
}
namespace AbstractFactoryDesignPattern
{
class BankBDebitCard : IDebitCard
{
#region IDebitCard Members
public string PayFromDebitCard()
{
return "Pay through Debit Card From Bank B";
}
#endregion
}
}
Client - Program.cs class
namespace AbstractFactoryDesignPattern
{
class Program
{
static void Main(string[] args)
{
BankFactory obj = new BankFactory();
IPay objPay;
ICreditCard objCreditCard;
IDebitCard objDebitCard;
string strBank;
Console.WriteLine("Enter Your Bank to Know the options");
Console.WriteLine();
strBank = Console.ReadLine();
objPay = obj.PayOption(strBank);
objCreditCard = objPay.GetCreditCardDetails();
objDebitCard = objPay.GetDebitCardDetails();
Console.WriteLine(objCreditCard.PayFromCreditCard());
Console.WriteLine(objDebitCard.PayFromDebitCard());
Console.ReadLine();
}
}
}
The output is as shown below.
For any doubts contact me at here