Factory Method Pattern


In the previous article you might have read about Abstract Factory. It says about abstracting a class with related objects. In this article we are discussing the Factory Method pattern. I am using the same ADO.NET Provider Factory class as the example.

Let us see the challenge and evolve to the solution.

Challenge

You are working on a windows application. The application has 2 types of users based on the database license they have: SQL Server or Oracle.

So for each database operation you need to create the right database classes based on an enumeration DatabaseType.

public void InsertRecord()
{
    if (AppContext.DatabaseType == DatabaseType.SqlServer)
    {
        SqlConnection connection = new SqlConnection();
        SqlCommand command = new SqlCommand();

        command.Connection = connection;
        command.ExecuteNonQuery();
    }
    else if (AppContext.DatabaseType == DatabaseType.Oracle)
    {
        OracleConnection connection = new OracleConnection();
        OracleCommand command = new OracleCommand();

        command.Connection = connection;
        command.ExecuteNonQuery();
    }
}


The above code seems to be complex and needs repeating for each database operation spread throughout the application.

How to stop the repeating code and make things better?

Definition

"Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses."

Implementation

The above problem can be resolved using Factory Method pattern. Here we provide an abstract class for defining the structure and associating all related objects (using Abstract Factory). Then the sub classes will be created deriving from this abstract class. The sub classes decide which classes to be instantiated.

The advantage is more quality and less code. Here we have to define an abstract class named DbProviderFactory. (already ADO.NET contains it)

public abstract class DbProviderFactory
{
public virtual DbCommand CreateCommand();
public virtual DbCommandBuilder CreateCommandBuilder();
public virtual DbConnection CreateConnection();
       public virtual DbDataAdapter CreateDataAdapter();
       public virtual DbParameter CreateParameter();
}

Then from the above abstract class we can derive concrete classes.

public class SqlClientFactory : DbProviderFactory

    public override DbConnection CreateConnection()
    {
        return new SqlConnection();
    }

    public override DbCommand CreateCommand()
    {
        return new SqlCommand();
    }
}


You can see from the above code SqlConnection() and SqlCommand() objects are created and supplied for DbConnection and DbCommand types respctively. Here DbConnection and DbCommand are other abstract classes.

Similarly the Oracle implementation follows:

public class OracleClientFactory : DbProviderFactory
{
    public override DbConnection CreateConnection()
    {
        return new OracleConnection();
    }

    public override DbCommand CreateCommand()

    {
        return new OracleCommand();
    }
}


Replacing the Original Code

Now we are ready to replace our Insert() method code with the Factory Method classes. Here we are using an AppInit() code to create the factory which will be used throughout the application.

public void AppInit()
{
    if (AppContext.DatabaseType == DatabaseType.SqlServer)
        AppContext.DbProviderFactory = SqlClientFactory.Instance;

    else if (AppContext.DatabaseType == DatabaseType.Oracle)
        AppContext.DbProviderFactory = OracleClientFactory.Instance;

// NewInsertRecord method
private void NewInsertRecord()
{
    DbConnection connection = AppContext.DbProviderFactory.CreateConnection();
    DbCommand command = AppContext.DbProviderFactory.CreateCommand();

    command.Connection = connection;
    command.ExecuteNonQuery();
}


From the above code you can see that using Factory Method the code is reduced considerably but at a cost of new classes. The pattern provides much flexibility on adding a new database. (if another customer with PostgreSQL arrives)

Abstract and Concrete Derivation

The following image depicts the relation between the abstract and concrete classes we have discussed.

FacMethod.gif

Note

ADO.NET already includes the DbProviderFactory abstract class and concrete classes like SqlClientFactory, OleDbFactory etc. Additionally, using an ORM like Entity Framework automatically takes care of the database switching. The scenario mentioned here is for learning purposes.

Summary

In this method we have seen the Factory Method pattern. The example we discussed is included with the attachment.
 


Similar Articles