One of the most widely used designing patterns for a application is the Factory Pattern. But many of the upcoming developers do not have a clear idea of what is it all about and why is it useful. If you search the internet for it, you will find tons and tons of articles about it but after reading them you will end even more confused ! So in this article I would be explaining the Factory Pattern from a different perspective with the help of real world examples which would help you to understand it easily and for life-time.
Introduction - Why do we need such patterns
Before such coding and design patterns were introduced programming was done in a sequential manner. In order to understand how did the patterns came into existence one has to understand the background to it. We have to understand the evolution of coding style and programming languages. For this let us go backwards into time and see how was coding done. The real programming language that came into existence first and had a global acceptance was the C language. It was invented by Dennis Rithie in the year 1972. It provided the developer with lot of choice option and many new features were introduced which were a breakthrough and innovative at that time. Firstly say if we have a code that does some operation, like addition of two numbers, and this operation is required in our program many times, then we have the challenge of how to reuse the existing code. For this the functions were used in the C language. We just needed to make a function and call it whenever we required that particular set of code to run. This hugely helped in re-use of the existing code and the updation and maintainability increased. Now an interesting fact, the name of C language was given after this very feature. C actually denotes the word "SEA" and this language was at time regarded as "Sea of Functions" as one can make as many functions that they want. The programmer by using this feature was now able to make huge applications that were impossible earlier.
But with passing of time the demand for creation of more complex programs that can solve complex problems arise. The focus now shifted to making the applications more close to the real world like situation so that the developer and user can easily co-relate them. Thus the era began where the real-world like features were now being asked. Further the problem with the C language was that after one point of time the number of functions in an application became very large and due to this the problem of maintainability arise. Further the re-usability of code written in functions was also limited. To solve all these problems OOPs was introduced. OOPs is Object Oriented Programming. In this the whole concept was around treating the various entities involved as objects and these objects were denoting run-time instances of a real world like entity called Class which exhibited the OOPs concepts. There concepts were inheritance, polymorphism, abstraction, encapsulation etc. They helped the developer now to map the real world like problems and their properties to the programming language by the use of Class and OOPs. This became a turning point in the programming world and opened new ways by which one can manipulate complex problems and yet they are just like real world entities. With time the problem and applications being developed become even more complex and now were not even properly managed by the OOPs concepts alone. What was felt that OOPs was a great way to manage problems but something was holding the developer to harness the full power of it. And to overcome this the Design Patterns came into existence. Here the design patterns were applied onto the OOPs concept enabled applications and the output was really encouraging and opened up new areas of research and changed the way the architects and developers used to look at the way one develops applications.
Now after all the above talk let us see that how does the design pattern helps the developers. Now consider that we have an application where there are many heads that need to full-fill the various functionalities, for eg. our application is for a school, now here we have many heads like teachers, students, parents, Office-Staff. Now we make various classes for each and each is managed in its own properties and environment. Now in order for the developer to use the desired head one have to manually make the entities of the various heads and have to know how to manage them. Now imagine that these head increase to 30, now it becomes very tedious task of remembering all the class names which come under the various heads and then make their objects and call their functions. Now take into picture that this project is being developed by a team of 10 people then all of them have to know the various classes that are involved in order to code for them. At one point this becomes unmanageable. Also if one have to add some new heads or some new functionality they have to have a complete knowledge of all the classes before adding any new functionality or classes. To solve all these type of issues the design patterns were introduced. Now I am going to discuss one such pattern in particular i.e. Factory Pattern.
The Savior - Factory Pattern
To solve all the above mentioned problems came into picture the Factory Pattern. In order to help you understand this patterns I am going to take a real world situation where one can co-relate and understand easily what all happens in this pattern. Consider that there is a office that is having four different departments. The office is having a four storey building and each department is in different floor. Now a Pizza delivery boy comes to the company to deliver the pizza. Now we are going to consider the senarios where we do not use Factory Pattern and when we use factory pattern.
When we do not use the Factory Pattern
In this case the Pizza delievery boy has to learn in which floor which department is situated and then go there accordingly to deliver the pizza. Now this can be quite a task for the pizza delievery boy as he has to gone at various places all during the day to deliver the pizza and he may not remember everytime where the exact department is in the building. Also now increase the number of departments in he building to 50 and the building to 50 floors so that each floor is having one department.
Now it becomes near impossible for the pizza delivery boy to remember which department is in which floor. Further say after 2 months some departments are shifted from their respective floor to some other floors. Now the pizza delivery boy on his next visit will get lost and only after someone updates him about the new arrangement he will be able to deliver the pizza. Now keep in mind that the pizza delivery boy has to perform all this operation in minimum time as time is a deciding factor in the efficiency of the delivery boy.
Now to make the problem more complex, consider that each department has teams where the respective team members sit. The teams sit together is different parts of the floor where the department is based. Now the pizza delivery boy has to deliver the pizza to the specific person he has to know the department, then the team and then only he can track the concerned person and deliver the pizza. Now different departments are having different number of teams of different sizes and types.
Now if take a simple situation where the number of departments are around 50 and each department is having around 10 teams. Now that makes around 500 teams ! This much information for the pizza delivery boy to remember and nearly impossible.
Now to map this problem with the real situations while designing and coding for the application. For this replace the pizza delivery boy with the developer. The departments with the namespaces relating to different functionality and classifications (like student, teacher, parent, staff etc.) and teams with the classes and the persons in the team with the functions in the classes. Now as a developer you have to call a particular function of a class then you need to know that it is in which namespace and under which classification, then he class and finally the function. So if there as many classes as described in the pizza delivery boy example then it is nearly impossible for the developer to know who is where. Also consider the problem that the pizza delivery boy faced when the floors of the departments were changed or new departments were added. In the same manner if new classes are introduced in the namespace or the name of the classes are changed then the coder needs to be updated about every minute detail. Also he would be fed-up by again and again creating objects of different classes at one time might be even confused by their names.
When we use the Factory Pattern
Now I am going to discuss what happens when we are going to use the Factory Pattern in the pizza delivery boy problem. Now for introducing the factory pattern to his problem let us introduce the reception in the company office building. Now when the pizza delivery boy reaches the company office he goes to the reception. Here he tells that he has got the order from Mr. XYZ that is from Department A Team T. The person sitting at the reception has all the details where all the departments, teams and its team members are situated. He tells the pizza delivery boy of the exact details of where he needs to go in order to deliver the order. Now the introduction of reception helps the pizza delivery boy need not know the exact internal details of where which department and team is present. He is more concerned in delivering the pizza to the right guy in time. Further if a department and team place or floor is changed it is managed by the reception, the pizza delivery boy neednot know the internal details and the changes in it. Also if in future new department is introduced of new team is made its information will be maintained by the reception and no effect on the pizza delivery boy as such.
Now map this problem with the real situations while designing and coding for the application. For this replace the pizza delivery boy with the developer. The departments with the namespaces relating to different functionality and classifications (like student, teacher, parent, staff etc.) and teams with the classes and the persons in the team with the functions in the classes. Now the developer need not remember all the details of the various namespaces and classes. Here replace the reception with the factory creator which creates the objects of the desired classes and passes them to the user for them to consume them. So no matter how many classes are there or how many classes are modified, deleted or added they all are maintained by the factory creator and no effect on the developer using them.
Factory Pattern Example
Now given the example above by which one can be quite clear of what all is happening in the factory pattern and why are they needed here we are going to demonstrate the same with the help of an program. Following figure show the structure of our application:
Here we have got three different namespaces that denote three different functionality of Parent, Student and Teacher and they have got respective classes in them that manages some functionality for each one of them. These classes are consumed by the Program.cs class. Now to implement the Factory Pattern we have used an interface and a class. The interface name is IFactoryInterface.cs and name of Factory Creator is MyFactory.cs.
Now before going any further I would like to bring into light some features of OOPs and Interfaces which would be helpful in understanding the logic we are going to implement for Factory Pattern.
- We can create a variable of a interface but we cannot create a object of an interface.
IMyInterface A = new IMyInterface(); Wrong
- Further the variable of the interface can contain the reference of the object of those classes that implement the interface.
- Lastly when we call a method from the interface variable that contains the reference of the object of the class that implements interface only those methods are called whose class reference is in the interface variable.
IFactoryInterface.cs
namespace pattern1
{
public interface IFactoryInterface
{
void AddName(string name);
string PrintName();
}
}
TheParent.cs
namespace pattern1.Parent
{
public class TheParent : IFactoryInterface
{
string n;
public void AddName(string name)
{
n = name;
}
public string PrintName()
{
return n;
}
}
}
TheStudent.cs
namespace pattern1.Student
{
public class TheStudent : IFactoryInterface
{
string n;
public void AddName(string name)
{
n = name;
}
public string PrintName()
{
return n;
}
}
}
TheTeacher.cs
namespace pattern1.Teacher
{
public class TheTeacher : IFactoryInterface
{
string n;
public void AddName(string name)
{
n = name;
}
public string PrintName()
{
return n;
}
}
}
MyFactory.cs
namespace pattern1
{
public class MyFactory
{
public static IFactoryInterface CreateObject(string type)
{
switch (type)
{
case "Parent":
return new Parent.TheParent();
case "Student":
return new Student.TheStudent();
case "Teacher":
return new Teacher.TheTeacher();
default:
return null;
}
}
}
}
Program.cs
using System;
namespace pattern1
{
class Program
{
static void Main(string[] args)
{
IFactoryInterface ObjParent = MyFactory.CreateObject("Parent");
IFactoryInterface ObjStudent = MyFactory.CreateObject("Student");
IFactoryInterface ObjTeacher = MyFactory.CreateObject("Teacher");
ObjParent.AddName("John");
ObjStudent.AddName("Peter");
ObjTeacher.AddName("Collins");
Console.WriteLine( ObjParent.PrintName());
Console.WriteLine( ObjStudent.PrintName());
Console.WriteLine( ObjTeacher.PrintName());
Console.ReadKey();
}
}
}
When we run the program we get the following output:
The MyFactory.cs creates the object of the desired class as requested by the Program.cs and sends the object back the object created. Note that the return type of the MyFactory.cs class CreateObject() function is of IFactoryInterface type. This is because the object being returned can be of any type thus to handle it we have implemented the IFactoryInterface in all the classes whose object is to be made and it is the return type of the CreateObject() function.
Thus by the use of it we can easily create as many new classes or update as we want and we have to update only the CreateObject() function of the MyFactory.cs class. The consumer of this pattern i.e. the Program.cs class would not get affected in any way.
I hope by this post I have cleared your concepts regarding the design patterns and why do we need them. Also the implementation of the Factory Pattern given is elaboration and helpful. Do keep me updated with your views and suggestions on the topic.