Abstract Factory Pattern
Abstract Factory pattern is used to create concrete class instances without specifying the exact class type (ie, to create instance of a classe without specifying the exact class type). Abstract Factory Pattern is one of the Creational Design Patterns. Creational Design patterns are design patterns that handle object creation mechanisms.
The Abstract Factory Pattern Structure
- Abstract Factory: Declares an interface that creates abstract objects.
- Concrete Factory: Which implements the operations declared in the Abstract Factory. In Abstract Factory pattern, it may have multiple Concrete Factory classes.
- Abstract Product: Declares an interface that creates abstract result objects.
- Concrete Product: This will be the object created by the corresponding concrete factory. It implements the opreations declared in the Abstract Product.
- Client: Client will use only interfaces as part of Abstract Factory and Abstract Product.
For more clarification and step by step implementation of Abstract Factory Pattern, please go through the following example. The following application act as an interface for both Sql Server and Oracle databases. See how it is implemented.
Note: The following example does not cover the whole database functionality. It is just created to explain Abstract Factory pattern. Even though you can modify the code to accomplish the whole database functionality.A Real world Example for Abstract Factory Pattern
Class Diagram 1. First we will create an Abstract Product. The below code shows an interface ("IDatabaseHelper") which will act as an Abstract Product in our sample application.
public interface IDatabaseFactory
{
IDatabaseHelper CreateHelper();
}
Note: You can use either Inerface or an Abstract Class to create an Abstract Product.
2. Next we will create two Concrete Product which implements the Abstract Product. The classes "OracleDatabaseHelper" and "SqlDatabaseHelper" will be our Concrete Products in our sample application.
public class SqlDatabaseHelper : IDatabaseHelper
{
private System.Data.SqlClient.SqlConnection _connection;
public System.Data.IDataReader ExecuteReader()
{
//todo
return null;
}
public System.Data.DataSet ExecuteDataSet()
{
//todo
return null;
}
public int ExecuteNonQuery()
{
//todo
return 0;
}
public object ExecuteScalar()
{
//todo
return null;
}
public void OpenConnection()
{
_connection = new System.Data.SqlClient.SqlConnection();
//todo
}
public void CloseConnection()
{
_connection.Close();
//todo
}
}
public class OracleDatabaseHelper : IDatabaseHelper
{
System.Data.OleDb.OleDbConnection _connection;
public System.Data.IDataReader ExecuteReader()
{
//todo
return null;
}
public System.Data.DataSet ExecuteDataSet()
{
//todo
return null;
}
public int ExecuteNonQuery()
{
//todo
return 0;
}
public object ExecuteScalar()
{
//todo
return null;
}
public void OpenConnection()
{
_connection = new System.Data.OleDb.OleDbConnection();
//todo
}
public void CloseConnection()
{
_connection.Close();
//todo
}
}
3. Next we will create an Abstract Factory. Here "IDatabaseFactory" interface will be our Abstract Factory.
public interface IDatabaseFactory
{
IDatabaseHelper CreateHelper();
}
4. Next we will create a Concrete Factory which implements the Abstract Factory. Here "OracleDatabaseFactory" and "SqlDatabaseFactory" classes will act as Concrete Factory through our sample application.
Note: In Abstract Factory pattern, it is possible to have multiple Concrete Factory Classes which all implements the Abstract Factory. public class SqlDatabaseFactory : IDatabaseFactory
{
public IDatabaseHelper CreateHelper()
{
return new SqlDatabaseHelper();
}
}
public class OracleDatabaseFactory : IDatabaseFactory
{
public IDatabaseHelper CreateHelper()
{
return new OracleDatabaseHelper();
}
}
5. Next we can create a Client, which will use the Abstract Factory and Abstract Product. Here in our example class "DatabaseClient" acts as a client.
public class DatabaseClient
{
private IDatabaseHelper _helper;
public DatabaseClient(IDatabaseFactory factory)
{
_helper = factory.CreateHelper();
//do any other code if needed.
}
public IDatabaseHelper Helper
{
get
{
return _helper;
}
}
}
To use the above pattern you can follow the following sample.
DatabaseClient dbClient = new DatabaseClient(new SqlDatabaseFactory());
dbClient.Helper.OpenConnection();
//do other operations
dbClient.Helper.ExecuteNonQuery();
//do other operations
dbClient.Helper.CloseConnection();
I will upload the sample application later. You can try this example. Feel free to ask questions and doubts.