Design Pattern For Beginners - Part-2: Factory Design Pattern

Introduction

Before reading this article, please go through the following article.

Before writing this article, I searched using Google for the keywords "factory design pattern," As expected, I found many good articles with excellent examples. Then I started to think, "Why to write one more?" OK, then I thought, let's check each of them individually. I visited each of the top 10 (from the first page). They are tremendous but stuffy enough; all the articles maintain a typical style and are the same type. Somehow reality is absent.

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 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 companies within the same tech park) going towards the food court at lunchtime. 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 lunchtime, I was going for lunch as usual and heard a beautiful romantic song of love from someone's voice. I observed that a disabled fellow was singing and going just before me using his crutch (you know, walking stick). How happy is he? (Dear reader, I am not making fun of his physical disability. I mean to say, see how happy he is. However, sometimes we may not be a complete person.) I was thinking of being a physical challenger.

OK, now the staircase has come, and it's time to climb. I noticed that the guy (singing a song of love) just folded up his walking stick and, by holding the stair railing, began to climb down. I was thinking about how nice the stick is. Depending on demand, it's behaving.

My story ends here, and the walking stick is just one example of a factory class. A factory class serves the client's demands, and depending on the requirements, it supplies the proper form depending on the requirements.

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.

image1.gif

As the name implies, a factory is where manufacturing happens—for example, a car factory where many types of car manufacturing happen. Now you want a specific 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 make your friend smile.

OK, one thing is clear from our discussion; the factory class is a supplier class that makes the client happy by supplying their demand.

How to will you 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.

image3.gif

Though the code is pretty simple to understand, we will discuss it further. At first, we 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 story's hero. 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), we can soon 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, we can add many more models in the future. Suppose we add seven or even 10 (or your preferred number) more models. In that case, the client code will also not be affected 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; 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 supplying a different object form depending on conditions. Somehow both share an expected 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 factory class to do that; we will use a Dbfactory class from the .NET library.

Let's clarify our purpose again: "We will implement such a data access mechanism that is able to talk with various database vendors.".

Today you have developed one software product by targeting one of your clients who use SQLServer as their database. You have designed and implemented the necessary coding for SQLServer. At first, we will learn why we need to know. (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 leader of this product's team. After an hour of discussion, they will decide, "They need to change the data manipulation policy." It will take 30 days more to fix by five resources, and the budget for that is $$.

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.".

What "If we develop such a data-accessing mechanism that will be compatible with all database vendors"? OOHhh, it's getting very complex; we will not go further. 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 a sample output.

image2.gif

You can see that nowhere in the example have we written any database-specific ADO.NET code. We have used various methods of the Dbfactory class to create an object depending 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 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; modify the code as in the following:

provider =DbProviderFactories.GetFactory("MySql.Data.SqlClient"); 

We need to change the provider name; 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. I hope you enjoy it. 

Continue reading