Before reading this article, please go through the following article:
Before writing this article I searched using Google for the keywords "factory design pattern" and as expected I many good articles with nice examples. Then I started to think "Why write one more?" OK, then I thought, let's check each of them one by one. I proceeded to visit each of the top 10 (from the first page). They really are great but stuffy enough and all the articles maintain a common style and are the same type of article. Somehow there is an absence of reality.
And that led me to write one more on the same topic. Here we will try to understand that topic with realistic examples and a little fun. And we will enjoy the learning.
So, let's start with the Factory Design Pattern. As promised "We will try to understand the basic need at first before starting any design pattern.".
Let me start with a small practical event that I experienced just a few days before (yes just a few days). My present office is within one Tech Park and I see many ITians (yes, you are right, they work in various IT fields in many companys within the same tech park) going towards the food court at lunch time. Of course I am one of them. There is a long staircase in the middle of the food court (since the food court is underground).
One fine lunch time, I was going for lunch as usual and I was hearing a beautiful romantic song of love from someone's voice. I observed that a handicapped fellow was singing and going just before me using his crutch (you know, walking stick). I was thinking being a physical challenger how happy he is? (Dear reader, I am not making fun of his physical disability. I Just mean to say, see how happy he is? However sometimes we may not be a complete person.)
OK, now the staircase came and it's time to climb down it. I noticed that the guy (singing a song of love) just folds up his walking stick and by holding the stair railing began to climb down. I was thinking how the nice stick is? Depending on demand it's behaving.
My story ends here and the walking stick is nothing but one example of a factory class. A factory class is a class that serves the client's demands and depending on the requiremetns it supplies the proper form.
OK, we have talked too much; let's learn the simple structure of the Factory Design Pattern. We will initially see the logical stricture of the Factory Design Pattern.
As the name implies, a factory is a place where manufacturing happens. For example, a car factory where many types of car manufacturing happens. Now you want a certain model and it's always possible to produce it from this car factory. Again your friend's taste is different from yours. He wants a different model; you can request a car factory again to bring a smile to your friend's face.
OK, one thing is clear from our discussion; the factory class is nothing but a supplier class that makes the client happy by supplying their demand.
How to will implement it in C# code? OK let's see the following example.
using System;
using System.Collections;
using System.Data.SqlClient;
using System.Threading;
namespace Test1
{
public interface ISupplier
{
void CarSupplier();
}
class namo : ISupplier
{
public void CarSupplier()
{
Console.WriteLine("I am nano supplier");
}
}
class alto : ISupplier
{
public void CarSupplier()
{
Console.WriteLine("I am Alto supplier");
}
}
class CarFactory
{
public static ISupplier GiveMyCar(int Key)
{
if (Key == 0)
return new namo();
else if (Key == 1)
return new alto();
else
return null;
}
}
class Program
{
static void Main(string[] args)
{
ISupplier obj = CarFactory.GiveMyCar(0);
obj.CarSupplier();
obj = CarFactory.GiveMyCar(1);
obj.CarSupplier();
Console.ReadLine();
}
}
}
And here is the output.
Though the code is pretty simple to understand, we will discuss it a little more. At first we have created one interface and implemented that interface within two classes. The classes are nano and alto.
In addition to them there is one more class called CarFactory and it is the hero of the story. If we observe closely, inside the CarFactory class we will find the mechanism to create a car. Though, here we are producing two low-end cars (nano and alto), in the near future we can add many more models. Now here is the original beauty of the factory class.
Try to understand the following few lines carefully. As we indicated previously, we can add many more models in the future. If we add 7 or even 10 (or your preferred number) more models, then the client code will also not be effected by a single line, because we will add code in the factory class, not in the client and will inform the client that, from now on, those models are also available; just send the proper code (such as 0 for nano, 1 for alto) to get them.
Now return to my story of a walking stick. The walking stick was changed in behavior depending on needs. And just now we have seen our factory class also supplying a different form of object depending on needs. Somehow both are sharing a common behavior, right?
OK, now you may think, what a useless example this is? Car class? We don't know when our company will get a project from a car merchant and we will implement the CarFactory class there.
Ok, then let me show you a very realistic example that you can implement in your current project, yes tomorrow morning.
Here we will learn how to implement a vendor-independent data access mechanism using a factory class. No, we will not create our own factory class to do that; we will just use a Dbfactory class from the .NET library.
Let's clarify our purpose one more time: "We will implement such a data access mechanism that is able to talk with various database vendors.".
At first we will learn why we need to learn. Today you have developed one software product by targeting one of your clients who uses SQLServer as their database. You have designed and implemented necessary coding for SQLServer. (Yes ADO.NET code, sqlconnection, sqlcommand bla bla..)
Now tomorrow the client may say that we are not happy with SQLServer and we have decided that from now we will use Oracle as our backend database.
The drama starts here. Let me explain the first scene.
By getting this proposal in the mail (from the client) the project manager will call the team lead of this product's team. After an hour of discussion they will make the decision "They need to change the data manipulation policy". It will take 30 days more to fix by 5 resources and the budget for that is a $$ amount.
Now the client has received mail from the Software Company and replied: "Why do you people disclose the matter at the very first and we are unable to give a single $ and day to do so. And we want to get it done within this time limit.".
OOHhh, it's getting very complex, we will not go farther. Anyway what "If we develop such a data accessing mechanism that will be compatible with all database vendors"? Have a look at the following code.
using System;
using System.Collections;
using System.Data.SqlClient;
using System.Threading;
using System.Data.Common;
using System.Data;
namespace Test1
{
class Program
{
static void Main(string[] args)
{
DbProviderFactory provider = null;
DbConnection con = null;
DbCommand cmd = null;
DbDataReader rdr = null;
DataTable dt = new DataTable();
provider =DbProviderFactories.GetFactory("System.Data.SqlClient");
con = provider.CreateConnection(); //Create Connection according to Connection Class
con.ConnectionString = "Data Source=SOURAV-PC\\SQL_INSTANCE;Initial Catalog=test;Integrated Security=True";
cmd = provider.CreateCommand(); //Create command according to Provider
try
{
cmd.CommandText = "select * from name";
cmd.CommandType = CommandType.Text;
if (con.State == ConnectionState.Closed || con.State == ConnectionState.Broken)
{
con.Open();
cmd.Connection = con;
using (con)
{
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (rdr.Read())
{
Console.WriteLine(rdr["nametest"].ToString());
Console.WriteLine(rdr["surname"].ToString());
}
}
}
}
catch (Exception ex)
{
throw;
}
finally
{
//trn.Rollback();
con.Dispose();
cmd.Dispose();
}
Console.ReadLine();
}
}
}
Here is sample output.
You can see that nowhere in the example we have written any database specific ADO.NET code. We have used various methods of the Dbfactory class to create an object dependiing on Supplier. Have a look at the following code:
con = provider.CreateConnection(); //Create Connection according to database provide cmd = provider.CreateCommand(); //Create command according to database provider
Here the provider is nothing but an object of the DbProviderFactory class and we are using a function like Createconnection() and CreateCommand() to initialize a connection and command object.
Now if you want to change the database then just change the provider name or database supplier name like:
provider =DbProviderFactories.GetFactory("System.Data.SqlClient");
Here we have provided our database provider as SQLServer and tomorrow, if you want to, you can use MySQL; just modify the code as in the following:
provider =DbProviderFactories.GetFactory("MySql.Data.SqlClient");
We just need to change the provider name and the rest of the code will work fine. And see again the DbProviderFactory class supplies an object depending on the user's demands and this is the beauty of a factory class.
Conclusion
This is my best attempt to explain a Factory Design Pattern with an example and in my own words. Hope you enjoy it.