Tuesday 23 December 2014

Factory pattern with a very basic example

Introduction

The factory pattern method is a popularly used design pattern and it is very useful to restrict clients from knowing the actual business logic methods, it is useful to create a decoupled system, and it is useful to eliminate object creation in a client environment.
This article explains how we can achieve these problems with a small example.

Problem

For example we have a scenario where based on user input we need to call particular class methods. I have a customer input screen. He enters his choice whether they want to buy a bike or a car. Normally we get input from the user and based on that will create an object in the client class and call those methods like below.
//
// customer enters their choice
//
If (choice == “Car”)
{
 // call car class and it’s methods
 Car c = new car();
 c.buy();
}
If (choice == “bike”)
{
 // call bike class and it’s methods
 Bike b = new Bike();
 b.buy()
}
...
  1. In case in future if there is any other vehicle added then we need to change the client functionality.
  2. The above client code depicts that there are classes CarBike, and a method Buy. There is no security at the client side.
  3. Need to use the new keyword in client classes.
To avoid these problems Factory pattern is used.

Solution

Problem 1

Create a new interface to depict methods, for example, in our scenario, it is Buy(). Using this interface it will solve problems 1 and 2.
//
// Interface
//
public interface IChoice
{
    string Buy();
}
A new class will be added and this class we will be called factory class. This class sits between the client class and the business class and based on user choice it will return the respective class object through the interface. It will solve problem 3.
//
// Factory Class
//
public class FactoryChoice
{
    static public IChoice getChoiceObj(string cChoice)
     {
        IChoice objChoice=null;
        if (cChoice.ToLower() == "car")
        {
            objChoice = new clsCar();
        }
        else if (cChoice.ToLower() == "bike")
        {
            objChoice = new clsBike();
        }
        else
        {
            objChoice = new InvalidChoice();
        }
        return objChoice;
    }
}
 
//Business classes
//Car
public class clsBike:IChoice
{
    #region IChoice Members
 
    public string Buy()
    {
        return ("You choose Bike");
    }
 
    #endregion
}
 
//Bike
public class clsCar:IChoice
{
 
    #region IChoice Members
 
    public string Buy()
    {
        return ("You choose Car");
    }
 
    #endregion
}
From the client class call the factory class object and it will return the interface object. Through the interface object we will call the respective method.
//Client class
IChoice objInvoice;
objInvoice = FactoryClass.FactoryChoice.getChoiceObj(txtChoice.Text.Trim());
MessageBox.Show(objInvoice.Buy());
In future if we need to add a new vehicle then there is no need to change the client class, simply return that object using the factory class.

Advantages

Suppose we want to add a decoupled structure and don’t want to disturb the client environment again and again, this pattern is very useful. The factory class will take all the burden of object creations.

----------------------Brief Description--------------------



Logical Flow

E.g. A Client, an object that requires an object of another class, say Car or Bike

 

Instead of creating the object of these classes directly, we introduce the new class calledFactory. Its primary responsibility is to create an object of other classes

The factory completely abstracts the creation and initialization of the other classes from the client

 
Q: How this will help?

A: Consider scenario where in future, if your client asked to introduce “Truck” in your implementation

You will handle these changes in factory class

 
CLIENT’S CODE REMAINS UNAFFECTED BY THESE CHANGES

Q: Wondering why we need this?

A: Say, we have to design a solution to get user’s input to create an object of “Car” or “Bike”

 
Assumption:

We have provided compiled library (DLL) to client, he/she can use these libraries to create different vehicle objects

Now client have implementation, where he/she takes input from user to create object of “Car” or “Bike”

Following code is the very first thing comes into our mind:

 
//This is client’s code

//Get user’s choice in “choice” variable

//

If (choice == “Car”)

{

            // call car class and it’s methods

            Car c = new car();

            c.buy();

}

If (choice == “bike”)

{

            // call bike class and it’s methods

            Bike b = new Bike();

            b.buy()

}

 
Issues here are:

1.       In future, if there is any other vehicle added, then we need to change the client functionality (it means, client will change his/her code)

2.       The above client code depicts that there are classes Car, Bike, and a method Buy. There is no security at the client side (no abstraction, violation of basic OOP concept)

3.       Need to use the new keyword in client classes (Object initialization at client code)

Solution:

Architecture:

1.       Create an interface to have the common method (here it is “buy()”)

2.       All the classes (Bike/Car etc.) will implement this interface

3.       Create a new class (act as factory class), which will have function to instantiate the object as per client’s input

This function will return object of the interface, This is the implementation ofabstraction (client will never know that object of which class is invoked, as he will always get an object of interface)

 
Lets see the code:

            Interface:

//
// Interface which will have common methods
//

public interface IChoice
{
    string Buy();
}
             
Classes:
//
//Car
//

public class clsBike:IChoice
{
    #region IChoice Members

    public string Buy()
    {
        return ("You choose Bike");
    }

    #endregion
}

//
//Bike
//

public class clsCar:IChoice

{
    #region IChoice Members

    public string Buy()
    {
        return ("You choose Car");
    }
    #endregion
}
          

            Factory Class:

 
//
// Factory Class
//

public class FactoryChoice
{
    static public IChoice getChoiceObj(string cChoice)
     {
        IChoice objChoice=null;
        if (cChoice.ToLower() == "car")
        {
            objChoice = new clsCar();
        }
        else if (cChoice.ToLower() == "bike")
        {
            objChoice = new clsBike();
        }
        else
        {
            objChoice = new InvalidChoice();
        }
        return objChoice;
    }
}

Now compile this to generate the DLL, and provide it to client
Client will include the reference of this DLL to reuse your classes and functionalities

How client will write code in his/her classes?:

Client code:
//
//Client class
//

IChoice objInvoice;
objInvoice = FactoryClass.FactoryChoice.getChoiceObj(txtChoice.Text.Trim());
MessageBox.Show(objInvoice.Buy());

Now if we get change request to add one more vehicle named “Truck”

 Add below class to your code, and update the factory class accordingly.  Now compile it and give the latest DLL to client

//
//TRUCK
//

public class clsTruck:IChoice
{
    #region IChoice Members

    public string Buy()
    {
        return ("You choose Truck");
    }
 
    #endregion
}

Change in client’s code: NO CHANGES !!!


No comments:

Post a Comment