Learn Design Patterns - Factory Method Pattern

Agenda

In this article we will understand:

  • What is the Factory Method pattern and how is it defined by the GOF?
  • In what scenario should it be used? We will see a real-world and then a technical example and try to understand the problems with traditional approaches.
  • How does the Factory Method pattern solve the problems it solves?
  • What are the components involved in the Factory Method Pattern?
  • Make a code walkthrough by implementing Factory Method Pattern application.
  • Class diagram for Factory Method Pattern.

Previous Articles

  1. Design Patterns: Introduction
  2. Learn Design Pattern - Singleton Pattern

Definition

The Factory Method Pattern is the most commonly used design pattern in modern programming and it falls under the Creation Pattern; in other words it is related to object creation.

According to the Gang of Four: the "Factory Method Pattern defines an interface for creating an object, but let the subclasses decide which class to instantiate".
(We will explain this definition as we move further.)

When to use

Consider a situation

where a person that wants something first creates it and then uses it.

Example: if he wants to eat a "Good day biscuit" then he first creates it and then eats it, and when he wants "Parle G" he changes his creation method to create it and then eat it.

It's very difficult for him to survive if he keeps on constructing everything by himself. He wants someone (some kind of factory) to do this construction work for him so that he can concentrate on more important aspects of life.

Sorry if it's not a good example, I am not a creative guy, but I hope you understood what I was trying to explain.

Practical Example

Our Company ABC Corporation currently has 3 levels of customers Grade1, Grade2 and Grade 3.
Grade1 - > A Tax of 12% will be applied to the total amount
Grade2 - > A Tax of 30% will be applied to the total amount
Grade3 - > A Tax of 40% will be applied to the total amount

Our task is to create an option which will ask for Customer Name, Grade and Amount as input and display Final Amount.

Output

output-design-pattern.jpg

Coding

1. Create the Entities required like:

public class Grade1Customer

{       

          public string CustomerName{get;set;}

          public int Amount{          get;set;}

 

          public int GetTotalAmount()

          {

                   return (int)(Amount + (Amount * 0.12));             

          }

}

public class Grade2Customer

{       

          public string CustomerName{get;set;}

          public int Amount{          get;set;}

 

          public int GetTotalAmount()

          {

                   return (int)(Amount + (Amount * 0.30));

          }

}

2. Create the ASPX page and the following code behind:
 

switch(DdlGrade.SelectedValue)

{

          case "1":

          {

                   Grade1Customer obj = new Grade1Customer()

                   {

                             CustomerName=TxtName.Text,

                             Amount=int.Parse(TxtAmount.Text)

                   };

                   Response.Write("Welcome "+TxtName.Text+", Your toal unpaid amount is "+obj.GetTotalAmount().ToString());

          }

          break;

          case "2":

          Grade2Customer obj2 = new Grade2Customer()

                   {

                             CustomerName=TxtName.Text,

                             Amount=int.Parse(TxtAmount.Text)

                   };

          Response.Write("Welcome " + TxtName.Text + ", Your toal unpaid amount is " + obj2.GetTotalAmount().ToString());

          break;        

}


Problem

  • Grade Customers are directly connected to client code which leads to many new keywords and thus the code becomes cluttered.

  • Consider that the company wants to add one more level of customer say Grade3, and it requires

  • Creating one more class Grade3Customer.

  • The additional case statement in client code leads to recompiling of the client code.

Changes are the integral part of Software Development and the solution for them is creating a loosely coupled system.

Factory Method Pattern as solution

Let's redefine the Factory Method Pattern in simpler terms.

It says:

  • First define an interface, which will provide a method, using which we can get the required object.

  • Derive a subclass from the interface which actually does the construction part (using the new keyword and Concrete classes like Grade1Customer) as per the specification.

This pattern is termed factory because it implements the concept of real-world factories, i.e., creating something. And here are the objects being created:

The Components involved in the Factory Method Pattern are:

  • Product- IGradeCustomer

  • Concrete Product - Grade1Customer,Grade2Customer

  • Factory - ICustomerFactory

  • Concrete Factory - CustomerFactory.

Let's start coding,

Step 1

Create a base for concrete products, as in:
 

public interface IBaseCustomer

{

          int Amount {get; set; }

          string CustomerName {get; set; }

          int GetTotalAmount();

}


Step 2

Derive concrete classes from the above interface:

public class Grade1Customer : IBaseCustomer

Step 3

Create a Base Factory for creating contracts for other factories:
 

public interface ICustomerBaseFactory

{

          IBaseCustomer  GetCustomer(int CustomerType);

}


Step 4
 

public class CustomerFactory : ICustomerBaseFactory

{

          public IBaseCustomer  GetCustomer(string  CustomerType)

          {

                   switch(CustomerType)

                   {

                             case "1":

                                      return  new Grade1Customer();

                             case "2":

                                      return new Grade2Customer();

                             default:

                                      return null;

                   }

          }

}


Step 5

Write Client Code:
 

protected void BtnCalculate_Click(object sender, EventArgs e)

{

          ICustomerBaseFactory objFactory = new CustomerFactory();

          IBaseCustomer objCustomer = objFactory.GetCustomer(DdlGrade.SelectedValue);

 

          objCustomer.CustomerName = TxtName.Text;

          objCustomer.Amount = int.Parse(TxtAmount.Text);

 

          Response.Write("Welcome " + TxtName.Text + ", Your toal unpaid amount is " +                                                                                                                                                            objCustomer.GetTotalAmount().ToString());

         

}


(Creating separate class library for each component is a good practice)

Now the client code is not directly connected to concrete classes, they go through factories. There is no new keyword in the client code; the client code is easily extended for new customers because adding new customers requires recompilation of the factory, not client code.

Class Diagram

Factory-Method-Pattern-class-diagram.jpg

Conclusion

  • We just learned what is meant by Factory Method Pattern and how to implement them in asp.net and especially when.

  • Basically, the Factory Method Pattern allows us to program against interfaces, letting us plug in the actual implementation only when we need to.

  • We saw how the Factory Method Pattern can decouple the two classes.

I had covered the Singleton Patten in my last article about design patterns.

We are done with two creational patterns and now we pretty much understand how Creational design patterns abstract the instantiation process. They help make a system independent of how its objects are created, composed, and represented.

Hope you enjoyed the article, keep reading and comments are always welcome.