Wednesday, February 15, 2012

Design Patterns : Factory Pattern Implementation

  • Factory pattern is one of the types of creational patterns. You can make out from the name factory itself it’s meant to construct and create something. In software architecture world factory pattern is meant to centralize creation of objects. Below is a code snippet of a client which has different types of invoices. These invoices are created depending on the invoice type specified by the client. There are two issues with the code below:-
  • First we have lots of ‘new’ keyword scattered in the client. In other ways the client is loaded with lot of object creational activities which can make the client logic very complicated.

    Second issue is that the client needs to be aware of all types of invoices. So if we are adding one more invoice class type called as ‘InvoiceWithFooter’ we need to reference the new class in the client and recompile the client also.





Figure: - Different types of invoice



Taking these issues as our base we will now look in to how factory pattern can help us solve the same. Below figure ‘Factory Pattern’ shows two concrete classes ‘ClsInvoiceWithHeader’ and ‘ClsInvoiceWithOutHeader’.

The first issue was that these classes are in direct contact with client which leads to lot of ‘new’ keyword scattered in the client code. This is removed by introducing a new class ‘ClsFactoryInvoice’ which does all the creation of objects.

The second issue was that the client code is aware of both the concrete classes i.e. ‘ClsInvoiceWithHeader’ and ‘ClsInvoiceWithOutHeader’. This leads to recompiling of the client code when we add new invoice types. For instance if we add ‘ClsInvoiceWithFooter’ client code needs to be changed and recompiled accordingly. To remove this issue we have introduced a common interface ‘IInvoice’. Both the concrete classes ‘ClsInvoiceWithHeader’ and ‘ClsInvoiceWithOutHeader’ inherit and implement the ‘IInvoice’ interface.

The client references only the ‘IInvoice’ interface which results in zero connection between client and the concrete classes ( ‘ClsInvoiceWithHeader’ and ‘ClsInvoiceWithOutHeader’). So now if we add new concrete invoice class we do not need to change any thing at the client side.

In one line the creation of objects is taken care by ‘ClsFactoryInvoice’ and the client disconnection from the concrete classes is taken care by ‘IInvoice’ interface.



Figure: - Factory pattern

Below are the code snippets of how actually factory pattern can be implemented in C#. In order to avoid recompiling the client we have introduced the invoice interface ‘IInvoice’. Both the concrete classes ‘ClsInvoiceWithOutHeaders’ and ‘ClsInvoiceWithHeader’ inherit and implement the ‘IInvoice’ interface.

InterfaceAndConcrete.jpg

Figure :- Interface and concrete classes

We have also introduced an extra class ‘ClsFactoryInvoice’ with a function ‘getInvoice()’ which will generate objects of both the invoices depending on ‘intInvoiceType’ value. In short we have centralized the logic of object creation in the ‘ClsFactoryInvoice’. The client calls the ‘getInvoice’ function to generate the invoice classes. One of the most important points to be noted is that client only refers to ‘IInvoice’ type and the factory class ‘ClsFactoryInvoice’ also gives the same type of reference. This helps the client to be complete detached from the concrete classes, so now when we add new classes and invoice types we do not need to recompile the client.


Figure: - Factory class which generates objects



Another Example:


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.

Another Example

The job of the Factory design pattern is to create concrete sub classes. You can see the Factory design pattern used throughout the .NET Framework.
The essence of the Factory Pattern is to "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses." Factory methods encapsulate the creation of objects. This can be useful if the creation process is very complex, for example if it depends on settings in configuration files or on user input.
A C# example of the Factory Pattern
// A Simple Interface
public interface IVehicle
{
    void Drive(int miles);
}

// The Vehicle Factory
public class VehicleFactory
{
    public static IVehicle getVehicle(string Vehicle)
    {
        switch (Vehicle) {
            case "Car":
                return new Car();
            case "Lorry":
                return new Lorry();
            default:
                throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", Vehicle));
                break;
        }
    }
}

// A Car Class that Implements the IVehicle Interface
public class Car : IVehicle
{
    public void IVehicle.Drive(int miles)
    {
        // Drive the Car
    }
}

// A Lorry Class that Implements the IVehicle Interface
public class Lorry : IVehicle
{
    public void IVehicle.Drive(int miles)
    {
        // Drive the Lorry
    }
}


Reference:

No comments:

Post a Comment