Sunday, March 8, 2009

Abstract factory

In the previous blog you would have seen Factory Pattern, this blog we will go along with Common Developer (CD) to have a look at what is Abstract Factory. After getting his dream car CD was happily driving it and showing it off to his friends and colleagues. Seeing CD’ car one of his colleague Another Common Developer (ACD) wanted to get a car for himself. But his requirement was different. He wanted to try different models and then select the best. ACD was not particular about a brand unlike CD who was very much particular about the brand Hyundai and also the model i10. ACD wanted to test drive different brand cars and then finalise on one or two and choose from among the short listed ones. ACD approached CD to get some tips on buying a car. After listening to ACD’ requirement CD suggested that he can approach a multi car brand showroom rather than a particular brands showroom. Taking CD’ advice ACD went to multi brand showroom and test drove many cars and finally settled for Toyota Camry. ACD called CD and informed him about his choice.

After finishing the call CD’ developer mind kicked in and started thinking how to implement ACD’ requirement in software terms. He has already implemented Factory pattern for solving his requirement where he was clear on which car he wanted and which brand he is looking for. After giving some thought CD noted down the following points.

  • There will be a set of different classes than the one in factory where everything was Hyundai brand of cars.

  • Different factories needed to create these different classes.

After doing a research CD found out that the best way to approach this scenario is to make use of the Abstract Factory pattern. There are many variations to the Abstract Factory and CD decided to try the two variations (Actually there is only one Abstract Factory proposed by the GOF. But over a period variations popped up. The second Abstract Factory pattern described in this blog is the one proposed by GOF.) Lets see the first variation. For the first implementation CD decided to build the building blocks of Abstract Factory. For this CD needed to create the products which the different factories can create. He thought of changing his Factory pattern implementation to incorporate Abstract Factory. The initial class created for factory pattern is listed below on which CD is planning to add new car models.

image

To incorporate Abstract Factory CD added new cars of different manufacturer. He added Ikon, Fiesta and Fusion models from Ford, Camry and Corrola models from Toyota and City, Civic and Accord models from Honda. The new class structure is show below.

image

From the above class diagram one can see that the new models are inheriting from the same Abstract Car class. The Initial product development is over. Now comes the factory creation. This implementation you can say is an extension of the first factory implementation method we saw in Factory pattern. In the first implementation of factory pattern we had only a concrete factory to create all the Hyundai cars. In the Abstract Factory implementation we will have base class from which all the car factories will inherit. The base class can be an abstract class or an interface. CD is making use of an interface called ICarFactory. The code is pasted below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Products;

namespace Factory_Pattern.Factory
{
    interface ICarFactory
    {
        Car CreateCar(string theCarName);
        string CarModelsAvailable{get;}
    }
}

The interface, ICarFactory, has got a method called “CreateCar” which takes the car name as the string argument and returns a “Car” object. All the car factories will inherit from this interface and implement their car manufacturing methods. The other method in the interface is “CarModelAvailable”. This method will return a string which will list out the models available with the brand. The sample code of “HyundaiCarFactory” and “ToyotaCarFactory” is given below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Products;

namespace Factory_Pattern.Factory
{
    class HyundaiCarFactory : ICarFactory
    {
        Car ICarFactory.CreateCar(string carName)
        {
            Car hyundaiCar = null;

            if (!string.IsNullOrEmpty(carName))
            {
                switch (carName.ToLower().Trim())
                {
                    case "santro":
                        hyundaiCar = new Santro();
                        break;
                    case "i10":
                        hyundaiCar = new i10();
                        break;
                    case "i20":
                        hyundaiCar = new i20();
                        break;
                    case "sonata":
                        hyundaiCar = new Sonata();
                        break;
                    default:
                        throw new Exception("No such Hyundai cars available in our kitty.");                       
                }               
            }

            return hyundaiCar;
        }

        string ICarFactory.CarModelsAvailable
        {
            get
            {
                return "Models available: Santro, i10, i20 and Sonata.";
            }
        }
    }
}

“ToyotaCarFactory” code.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Products;

namespace Factory_Pattern.Factory
{
    class ToyotaCarFactory : ICarFactory
    {  
        Car ICarFactory.CreateCar(string carName)
        {
            Car toyotaCar = null;

            if (!string.IsNullOrEmpty(carName))
            {
                switch (carName.ToLower().Trim())
                {
                    case "camry":
                        toyotaCar = new Camry();
                        break;
                    case "corolla":
                        toyotaCar = new Corolla();
                        break;                  
                    default:
                        throw new Exception("No such Toyota model available in our kitty.");
                }
            }

            return toyotaCar;
        }

        string ICarFactory.CarModelsAvailable
        {
            get
            {
                return "Models available: Camry and Corolla.";
            }
        }
    }
}

As you can see both the factory codes are nothing great, they just check the string and return the appropriate car model. The class diagram for the factories is given below.

image

As you can see from the diagram all the car factories inherit from the same interface. Each one has its own implementation of the “CreateCar” method which does the work of creating the respective car models of the company. As the factories are ready CD needed a place to assemble the cars and deliver them to the customer. For assembling the car CD created a class called the “AssemblyFloor”. The code for the class is shown below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Factory;
using Factory_Pattern.Products;

namespace Factory_Pattern
{
    class AssemblyFloor
    {
        ICarFactory carFactory;

        AssemblyFloor(ICarFactory theCarFactory)
        {
            this.carFactory = theCarFactory;
        }

        public Car DeliverCar(string theCarName)
        {
            return carFactory.CreateCar(theCarName);
        }
    }
}

The “AssemblyFloor” takes an “ICarFactory” implemented object as an argument in its constructor and sets it to one of its member variable. The “DeliverCar” method takes the car name as a string and calls the appropriate method of the factory to create the car. With the assembly floor the requirement to implement Abstract Factory is completed. While doing a code walkthrough CD found out that he has nearly four factories for the different brands. To create the factories dynamically, CD came up with an idea to have a factory to create the dynamic factory. So he created a factory for factory. The code is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern.Factory
{
    class CarFactoryCreator
    {
        public static ICarFactory CreateCarFactory(string theFactoryName)
        {
            ICarFactory carFactory = null;

            if (!string.IsNullOrEmpty(theFactoryName))
            {
                switch (theFactoryName.ToLower().Trim())
                {
                    case "ford":
                        carFactory = new FordCarFactory();
                        break;
                    case "hyundai":
                        carFactory = new HyundaiCarFactory();
                        break;
                    case "toyota":
                        carFactory = new ToyotaCarFactory();
                        break;
                    case "honda":
                        carFactory = new HondaCarFactory();
                        break;
                    default:
                        throw new Exception("The requested factory is not available. Valid entries are Ford, Honda, Hyundai and Toyota.");                       
                }
            }

            return carFactory;
        }
    }
}

Please note a very important point, the above class is not a part of the Abstract Factory, it is just a helper factory class. The helper class will help to create the factories based on different user’ requirement. The factory and products to be created by the factory are in place. CD wrote a Showroom class to make use of all the classes and see the behavior of Abstract Factory. The code of Showroom class is pasted below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Factory;
using Factory_Pattern.Products;

namespace Factory_Pattern
{
    class ShowRoom
    {      
        static void Main(string[] args)
        {
            Console.WriteLine("Please provide your brand preference? " +
                "Allowed values: Ford, Honda, Hyundai and Toyota.");
            string brand = Console.ReadLine();
            ICarFactory carFactory = CarFactoryCreator.CreateCarFactory(brand);
            Console.WriteLine("Please provide the car you would like to " +
                "purchase from {0} brand? {1}", brand, carFactory.CarModelsAvailable);
            string carName = Console.ReadLine();
            AssemblyFloor assemblyFloor = new AssemblyFloor(carFactory);
            Car customerCar = assemblyFloor.DeliverCar(carName);
            Console.WriteLine("Your {0} car is ready to be delivered."
                , customerCar.CarName);
            Console.ReadLine();
        }
    }
}

With the above code the abstract factory implementation is pretty much done.

Next CD thought of implementing the second approach to Abstract factory (the original pattern proposed by GOF). The difference which CD noted between Abstract Factory first approach and the new approach which he is going to implement is that in the second approach the products don’t have a single base class like that of the first approach. Instead the second approach has a set of products which inherit from their own base class. In the first approach all the products had a common base class whereas in the second approach each set of class had their own base class. Also the factory in the second approach will have the methods to create more than one product. Confused? Lets take the same car e.g. and work it out to have a better understanding. As CD found out that different products will have different base classes and they inherit from them, he decided to rework his class structure. CD kept the same base class structure for the car hierarchy, in addition to that he introduced new classes called “Engine”, “Chassis”, “Axle”, and “Wheel” which an integral part of a car. To incorporate the new classes in car CD changed the base “Car” class as shown below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Car_Parts.Engine;
using Factory_Pattern.Car_Parts.Chassis;
using Factory_Pattern.Car_Parts.Axle;
using Factory_Pattern.Car_Parts.Wheel;

namespace Factory_Pattern.Products
{
    public abstract class Car
    {
        private IEngine _iEngine;
        private ICarChassis _iCarChassis;
        private IAxle _iAxle;
        private IWheel _iWheel;

        public IEngine Engine
        {
            get
            { return this._iEngine; }
            set
            { this._iEngine = value; }
        }

        public ICarChassis Chassis
        {
            get
            { return this._iCarChassis; }
            set
            { this._iCarChassis = value; }
        }

        public IAxle Axle
        {
            get
            { return this._iAxle; }
            set
            { this._iAxle = value; }
        }

        public IWheel Wheel
        {
            get
            { return this._iWheel; }
            set
            { this._iWheel = value; }
        }

        public abstract float CC
        { get; }
        public abstract float Length
        { get; }

        public abstract float Width
        { get; }

        public abstract float Height
        { get; }

        public abstract float GroundClearance
        { get; }

        public abstract float MaxPower
        { get; }

        public abstract float MaxTorque
        { get; }

        public abstract float MaxSpeed
        { get; }

        public abstract float TankCapacity
        { get; }

        public abstract bool StartCar();

        public string CarName
        {
            get{ return this.GetType().Name; }
        }       
    }
}

You can see CD has added all the new parts of the car to the base abstract class. I need not explain why this approach was taken, as there can be no car without an engine, wheel etc. The abstract “Car” will form the base for all other Car classes. The class diagram with the inheritance is shown below.

image

One can see there is no change to the hierarchy other than the introduction of new properties. Next we can have a look at the different parts needed for the car. First we will see the wheel. The class diagram for wheel is shown below.

image

As one can see from the above diagram the base for wheel is an interface called IWheel. IWheel is inherited to the respective car’ wheel class, in the above case, it is inherited to HyundaiWheel class. From the “HyundaiWheel” the different model’ wheel has been extended. The code for the above implementation is pasted below.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern.Car_Parts.Wheel
{
    public interface IWheel
    {
        int Diameter { get; set; }
    }

    class HyundaiWheel : IWheel
    {
        #region IWheel Members

        int IWheel.Diameter
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        #endregion
    }

    class SantroWheel : HyundaiWheel
    {
    }

    class i10Wheel : HyundaiWheel
    {
    }

    class i20Wheel : HyundaiWheel
    {
    }

    class SonataWheel : HyundaiWheel
    {
    }

    class AccentWheel : HyundaiWheel
    {
    }
}

The above code is self explanatory. Next CD created engine. Here also the same concept is followed. An interface called IEngine which is implemented by the respective brand’ engine i.e. ToyotaEngine. ToyotaEngine is extended to implement the car specific engine like CamryEngine and CorollaEngine for Camry and Corolla models respectively. Why we have an interface for the engine is that every brand will have its own way of designing the engine, with interface we can give the freedom and also keep the contract in tact. Why we have a common class, ToyotaEngine, is that each brand will have there own common set of feature. The IEngine interface acts as the base for all the other cars engine. Honda implements IEngine to HondaEngine base class and then extends it to CityEngine, CivicEngine and AccordEngine. Similarly every brand follows the same concept.

image

 

image

The chassis also follows the same concept of an interface; interface implemented to a base class and then the base class is extended to create other model specific chassis.

image

Now this is an overkill of example I know but just to complete the car we need an axle also. The same concept is applied here also. I will not go into the details. CD has completed all the base classes needed for the abstract factory, now he has built the factories which will create these products.

The factory will have a base factory which again can be an interface or an abstract class and from this the other factories will implement/inherit the features. As CD already had an interface he decided to modify the “ICarFactory” interface used in the first implementation of abstract factory. To the “ICarFactory” he introduced four more methods to create the car engine (CreateEngine), to create car axle (CreateAxle), to create car chassis (CreateChassis) and finally to create wheel he incorporated “CreateWheel” method. After making changes to the interface CD implemented the interface to the car manufacturing factories. Few factories with the interface implementation are shown below.

image

As you can see the factories, HondaCivicFactory, FordFiestaFactory, HondaCityFactory and FordIkonFactory are implementing the interface ICarFactory. Similar to this all factories for the various models will implement the interface. The sample code for “FordFiestafactory” is shown below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Car_Parts;
using Factory_Pattern.Car_Parts.Axle;
using Factory_Pattern.Car_Parts.Chassis;
using Factory_Pattern.Car_Parts.Engine;
using Factory_Pattern.Car_Parts.Wheel;
using Factory_Pattern.Products;

namespace Factory_Pattern.Factory
{
    class FordFiestaFactory : ICarFactory
    {      
        Car ICarFactory.CreateCar(string theCarName)
        {
            return new Fiesta();                       
        }

        string CarModelsAvailable
        {
            get { return "Fiesta."; }
        }

        IAxle CreateAxle()
        {
            return new FiestaAxle();
        }

        ICarChassis CreateChassis()
        {
            return new FiestaChassis();
        }

        IEngine CreateEngine()
        {
            return new FiestaEngine();
        }

        IWheel CreateWheel()
        {
            return new FiestaWheel();
        }
    }
}

Next CD needed an assembling unit where the cars can be assembled. So CD created an “AssemblyFloor” class where cars can be assembled based on the dynamic factory passed. The AssemblyFloor code is shown below.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Factory;
using Factory_Pattern.Products;

namespace Factory_Pattern
{
    class AssemblyFloor
    {
        ICarFactory carFactory;

        public AssemblyFloor(ICarFactory theCarFactory)
        {
            this.carFactory = theCarFactory;
        }

        public Car AssembleCar(string theCarName)
        {
            Car assembledCar = this.carFactory.CreateCar();
            assembledCar.Chassis = this.carFactory.CreateChassis();
            assembledCar.Engine = this.carFactory.CreateEngine();
            assembledCar.Axle = this.carFactory.CreateAxle();
            assembledCar.Wheel = this.carFactory.CreateWheel();
            return assembledCar;
        }
    }
}

With the AssemblyFloor CD finished his basic requirement for the abstract factory pattern. CD created “ShowRoom” class to test the working of the abstract factory implementation. Pasted below is the code of the “ShowRoom” class.

using System;
using System.Collections.Generic;
using System.Text;
using Factory_Pattern.Factory;
using Factory_Pattern.Products;

namespace Factory_Pattern
{
    class ShowRoom
    {      
        static void Main(string[] args)
        {
            Console.WriteLine("Please provide your brand preference? " +
                "Allowed values: Fiesta, Ikon, Fusion, i10, i20, santro, sonata etc.");
            string carName = Console.ReadLine();
            ICarFactory carFactory = CarFactoryCreator.CreateCarFactory(carName);
            AssemblyFloor assemblyFloor = new AssemblyFloor(carFactory);
            Car customerCar = assemblyFloor.AssembleCar(carName);
            Console.WriteLine("Your {0} car is ready to be delivered."
                , customerCar.CarName);
            Console.ReadLine();          
        }
    }
}

After implementing the above abstract factory pattern CD took his notepad to jot down the following.

GOF definition of abstract factory:

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

What is the problem this pattern solves?

When you have set of related objects or dependent object then you go for Abstract Factory. As seen in the e.g. above we are creating related objects of car like engine, axle etc, so scenario similar to this can be solved using Abstract factory.

How it Solves the Problem?

To solve the problem we identify a set of related or dependent classes and provide a base class for these related classes to inherit. Then we define the Abstract Factory class and this class is inherited by concrete factories. The abstract factory class has the methods to create the related or dependent classes but the freedom is given to derive classes to implement their own ways of implementing the logic.

Participants of the Pattern.

  • Abstract Factory – in our e.g. the IcarFactory is the abstract factory.

  • Concrete Factory – FordFiestaFactory, FordIkonFactory, HondaCivicFactory etc are concrete factories

  • Abstract Product – Car, IWheel, IChassis, IEngine etc are e.g.

  • Product – Fiesta, Ikon, i10, i20, Camry, Corolla etc are e.gs.

  • Client – Assembly floor is the client.

Real time e.g.

In .NET factory is implemented in page life cycle where “PageHandlerFactory” is used to create an ASP.NET page handler dynamically to process ASP.NET page requests. Other factory implementation in .net are “WebServiceHandlerFactory”, “SimpleHandlerFactory”, “HttpRemotingHandlerFactory” to handle, webservice, simple handlers, remoting requests respectively. Also you can find the implementation of factory in WebRequest class’ Create method, AppDomain’ CreateDomain method et all.

So with this CD was clear on Abstract Factory pattern and I hope the same is the case with the reader' of this blog.

In the next blog we will see the difference, CD found out between Factory and Abstract Factory pattern.

Love Patterns,

Sandeep

Thursday, January 15, 2009

Factory Pattern

After long I am blogging something on design pattern. When I started writing about design pattens, the idea was to make everyone understand patterns in simple and understandable form as I have seen many think Patterns are hard to imbibe. But after posting my first blog, singleton, I was not quite happy with the way it was written. There was nothing different. The usual stuff. So I went to an ideating mode where I was conceptualizing how to write in simple terms so that everyone can understand. I came across this book called "Head first Design patterns". I read the book and it was quite different from other books. Patterns explained using cartoons, pictures et all. I would recommend anyone who wants to learn design patterns to have a look at this book. I thought why not write something on those lines but drawing cartoons, images will be time consuming and I am not so great in drawing also. So I thought I will write my design pattern blog as a story and the hero of my story will be a Common Developer. This blog is the first in a series of blog which I am planning to write based on this idea. Hope it will be informative. In this blog we will take a look at Factory pattern from our hero' point of view. So we embark on our journey to learn design pattern with our Common Developer (CD).

The story starts when our Common developer gets a job as what else developer. He started earning money and over a period of time he decides to invest his money on a car. Since he is very fond of Hyundai brand of cars he decides to buy one. We know Hyundai has got different types of cars like the Santro, i10, i20, Accent, Sonata etc. To buy his dream car CD went to a Hyundai showroom and ordered the latest i10.

Our CD started thinking from a developer' point of view on how to implement this whole scenario into a Object Oriented (OO) software program. CD decided to reproduce the real life system in OO terms. To design the system CD decided to first design the classes for the various models of Hyundai car.

CD decided to make use of inheritance to design his car classes. He designed a base class called Car from which other types of cars like Santro, i10, i20 etc were extended. Why this approach? Our CD chose i10 as his choice of car but someone else can buy Sonata and to give extensibility CD made use of inheritance. For e.g. in future say Hyundai introduces some new model then CD may be easily able provide extensibility. The classes designed by CD is shown below.

clip_image002

So from the above diagram we can infer that we have a common base class called car which is an abstract class from which all the other classes are inherited. The reason why CD decided to keep the “Car” as abstract is that Car class by itself doesn’t serve any purpose, only when it gets an implementation in the form of concrete classes like Santro, i10 etc it has some existence. Ultimately everyone wants car and every model is a car but they have different attributes like different Cubic Capacity, Max Power, Max Torque etc. The C# code for the “Car” and other inherited classes is given below.

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    public abstract class Car
    {
        public abstract float CC
        {
            get;
        }
        public abstract float Length
        {
            get;
        }

        public abstract float Width
        {
            get;
        }

        public abstract float Height
        {
            get;
        }

        public abstract float GroundClearance
        {
            get;
        }

        public abstract float MaxPower
        {
            get;
        }

        public abstract float MaxTorque
        {
            get;
        }

        public abstract float MaxSpeed
        {
            get;
        }

        public abstract float TankCapacity
        {
            get;
        }

        public abstract bool StartCar();

        public string CarName
        {
            get
            {
                return this.GetType().Name;
            }
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class Santro : Car
    {
        private float m_cc;
        private float m_lenght;
        private float m_width;
        private float m_height;
        private float m_groundClearance;
        private float m_maxPower;
        private float m_maxTorque;
        private float m_maxSpeed;
        private float m_tankCapacity;

        public Santro()
        {
            this.m_cc = 1086;
            this.m_lenght = 3565;
            this.m_width = 1525;
            this.m_height = 1590;
            this.m_groundClearance = 172;
            this.m_maxPower = 63;
            this.m_maxTorque = 89;
            this.m_maxSpeed = 141;
            this.m_tankCapacity = 35;
        }

        public override float CC
        {
            get
            {
                return this.m_cc;
            }           
        }

        public override float Length
        {
            get
            {
                return this.m_lenght;
            }           
        }

        public override float Width
        {
            get
            {
                return this.m_width;
            }           
        }

        public override float Height
        {
            get
            {
                return m_height;
            }
        }

        public override float GroundClearance
        {
            get
            {
                return this.m_groundClearance;
            }
        }

        public override float MaxPower
        {
            get
            {
                return this.m_maxPower;
            }
        }

        public override float MaxTorque
        {
            get
            {
                return this.m_maxTorque;
            }
        }

        public override float MaxSpeed
        {
            get
            {
                return this.m_maxSpeed;
            }
        }

        public override float TankCapacity
        {
            get
            {
                return this.m_tankCapacity;
            }
        }

        public override bool StartCar()
        {
            Console.WriteLine(base.CarName + " started.");
            return true;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class i10 : Car
    {
        private float m_cc;
        private float m_lenght;
        private float m_width;
        private float m_height;
        private float m_groundClearance;
        private float m_maxPower;
        private float m_maxTorque;
        private float m_maxSpeed;
        private float m_tankCapacity;

        public i10()
        {
            this.m_cc = 1086;
            this.m_lenght = 3565;
            this.m_width = 1595;
            this.m_height = 1550;
            this.m_groundClearance = 165;
            this.m_maxPower = 67;
            this.m_maxTorque = 99;
            this.m_tankCapacity = 35;
        }
        public override float CC
        {
            get
            {
                return this.m_cc;
            }
        }

        public override float Length
        {
            get
            {
                return this.m_lenght;
            }
        }

        public override float Width
        {
            get
            {
                return this.m_width;
            }
        }

        public override float Height
        {
            get
            {
                return m_height;
            }
        }

        public override float GroundClearance
        {
            get
            {
                return this.m_groundClearance;
            }
        }

        public override float MaxPower
        {
            get
            {
                return this.m_maxPower;
            }
        }

        public override float MaxTorque
        {
            get
            {
                return this.m_maxTorque;
            }
        }

        public override float MaxSpeed
        {
            get
            {
                return this.m_maxSpeed;
            }
        }

        public override float TankCapacity
        {
            get
            {
                return this.m_tankCapacity;
            }
        }

        public override bool StartCar()
        {
            Console.WriteLine(base.CarName + " started.");
            return true;
        }
    }
}

 

Now that CD has finished his base Car class design he decided to design the Hyundai factory which can create these cars. Here again CD can go with two approach that is he can have one factory for creating Hyundai cars or can go with different factories for different cars. CD decides to try both to understand them better.

CD decided to go with the first approach where he will have a single Hyundai factory to manufacture all the cars. In this approach CD created a Hyundai factory class with a method “CreateCar” which took string as an argument to create the choice of car CD wanted. Below is the code for the factory implementation.

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class HyundaiFactory
    {
        public Car CreateCar(string theCarType)
        {
            if (theCarType != null && theCarType != string.Empty)
            {
                if (theCarType.ToLower().Trim() == "santro")
                {
                    return new Santro();
                }
                else if (theCarType.ToLower().Trim() == "i10")
                {
                    return new i10();
                }
                else if (theCarType.ToLower().Trim() == "i20")
                {
                    return new i20();
                }
                else if (theCarType.ToLower().Trim() == "accent")
                {
                    return new Accent();
                }
                else if (theCarType.ToLower().Trim() == "sonata")
                {
                    return new Sonata();
                }              
            }

            return null;
        }
    }
}

You can see from the above class that we have a method called “CreateCar” which accepts a string as an argument and based on the argument the factory creates the car and returns the car of choice. Seeing the method signature we know why CD went ahead with the inheritance approach. He wanted the factory to be able to return any type of car and this is possible only through inheritance. Also car by itself doesn't have any existence unless it takes the form of Santro, i10, 120 etc. So the car class was declared abstract. CD was not happy with the current implementation, he wanted to make this approach more OO based , so he thought of changing the argument of the method to a class called “CarDescription”. The structure of the class is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class CarDescription
    {
        private string m_carName;
        private bool m_powerWindow;
        private bool m_powerSteering;
        private bool m_centralLocking;
        private string m_color;

        public string CarName
        {
            get
            {
                return this.m_carName;
            }
            set
            {
                this.m_carName = value;
            }
        }

        public bool PowerWindow
        {
            get
            {
                return this.m_powerWindow;
            }
            set
            {
                this.m_powerWindow = value;
            }
        }

        public bool PowerSteering
        {
            get
            {
                return this.m_powerSteering;
            }
            set
            {
                this.m_powerSteering = value;
            }
        }

        public bool CentralLocking
        {
            get
            {
                return this.m_centralLocking;
            }
            set
            {
                this.m_centralLocking = value;
            }
        }

        public string Color
        {
            get
            {
                return this.m_color;
            }
            set
            {
                this.m_color = value;
            }
        }
    }
}

Now using the above class CD was able to fine tune the features and customise his requirement like which color he wanted, whether he wanted power window, power steering, central locking etc for his choice of car. Once he thought of implementing the above class the signature of the factory method needed a change, he had two option either change the existing function to something like the one below or he can overload the method in the Hyundai factory. Anyway whatever options CD chose the signature of the method will look something like this.

public Car a CreateCar(CarDescription theCarDescriptor)

While trying to implement the new change he was faced with new problem, like, now he need to build the car based on many criteria and which could be complex. After much research he came to know, that, to build complex objects like car based on various criteria he can implement builder pattern. He decided he can extend the application and make use of builder pattern later as he was not very clear on builder pattern and implement builder in later stages when he has a sound knowledge of builder. Next he decided to create the showroom for ordering the cars. The showroom class is shown below.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class ShowRoom
    {
        static System.Collections.Hashtable hashTable = new
        System.Collections.Hashtable();
        static void Main(string[] args)
        {
            HyundaiFactory hyunFact = new HyundaiFactory();
            //Getting the car the user wants.
            Console.WriteLine("Allowed entries: Accent, i10, i20,
            Santro, Sonata");
            Console.WriteLine("Enter car you want to buy? ");
            string carType = Console.ReadLine();
            Car hyundaiCar = hyunFact.CreateCar(carType);
            //Displaying the car.
            Console.WriteLine("The car you ordered for: " +
            hyundaiCar.CarName);
            Console.WriteLine("Cubic Capacity: " +
            hyundaiCar.CC.ToString());
            Console.WriteLine("Max power: " +
            hyundaiCar.MaxPower.ToString());
            Console.WriteLine("Max torque: " +
            hyundaiCar.MaxTorque.ToString());
            Console.WriteLine("Fuel tank capacity: " +
            hyundaiCar.TankCapacity.ToString());
            Console.ReadLine();
        }
   }
}

So from the above code you can see how the car is created using the factory pattern using the first approach.

After completing the first option CD started implementing the second way of implementing the factory and wanted to see how it is different from the one he has already implemented.

In the second implementation of Factory, CD had to create a base factory called “HyundaiFactory”, from which his other car factories will be extended to create the individual car model factory. Below is the diagram depicting the class structure.

clip_image004

From the above diagram we can infer that CD has created a Base class called “HyundaiFactory” which is an abstract class. From this abstract factory all the other factories are inherited like the “HyundaiAccentFactory” (will create Accents cars), “Hyundaii10Factory” (will create i10 cars) etc. The code for the above class is shown below.

Abstract car factory code.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    public abstract class HyundaiFactory
    {       
        public abstract Car CreateCar();       
    }
}

Accent car factory code.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class HyundaiAccentFactory : HyundaiFactory
    {
        public override Car CreateCar()
        {
            return new Accent();
        }
    }
}

i10 car factory code.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class Hyundaii10Factory : HyundaiFactory
    {
        public override Car CreateCar()
        {
            return new i10();
        }
    }
}

i20 car factory code.

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class Hyundaii20Factory : HyundaiFactory
    {
        public override Car CreateCar()
        {
            return new i20();
        }
    }
}

Santro car factory code

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class HyundaiSantroFactory : HyundaiFactory
    {
        public override Car CreateCar()
        {
            return new Santro();
        }
    }
}

Sonata car factory code

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class HyundaiSonataFactory : HyundaiFactory
    {
        public override Car CreateCar()
        {
            return new Sonata();
        }
    }
}

From the above code one can see that each factory returns the car of a particular type. After completing the ground work for the factory pattern, CD created the “ShowRoom” class where he can make use of the factory and order the car of his choice. The “ShowRoom” class code is shown below.

The second factory implementation is given below

using System;
using System.Collections.Generic;
using System.Text;

namespace Factory_Pattern
{
    class ShowRoom
    {
        static System.Collections.Hashtable hashTable = new
        System.Collections.Hashtable();
        static void Main(string[] args)
        {
            // Creating all the factories and adding to the hashtable.
            hashTable.Add("accent", new HyundaiAccentFactory());
            hashTable.Add("i10", new Hyundaii10Factory());
            hashTable.Add("i20", new Hyundaii20Factory());
            hashTable.Add("santro", new HyundaiSantroFactory());
            hashTable.Add("sonata", new HyundaiSonataFactory());

            //Getting the car the user wants.
            Console.WriteLine("Allowed entries: Accent, i10, i20,
            Santro, Sonata");
            Console.WriteLine("Enter car you want to buy? ");

            string carType = Console.ReadLine();
            //Retrieving the factory fromt the collection.
            HyundaiFactory hyunFact =
            (HyundaiFactory)hashTable[carType.ToLower().Trim()];
            //Creating the car of the user' choice from the respective
            //factory.
            Car hyundaiCar = hyunFact.CreateCar();
            //Making use of the car.
            Console.WriteLine("The car you ordered for: " +
            hyundaiCar.CarName);
            Console.WriteLine("Cubic Capacity: " +
            hyundaiCar.CC.ToString());
            Console.WriteLine("Max power: " +
            hyundaiCar.MaxPower.ToString());
            Console.WriteLine("Max torque: " +
            hyundaiCar.MaxTorque.ToString());
            Console.WriteLine("Fuel tank capacity: " +
            hyundaiCar.TankCapacity.ToString());
            Console.ReadLine();
        }
    }
}

Now after completing the above implementation CD thought of understanding further on the pattern. So he decided he should know the following like the original definition given by GOF, what problem this pattern solves?, how it solves the problem?, and real time implementation. So he decided to note down all this. Below his what CD noted in his notepad for reference.

Gof Definition:

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

What is the problem this pattern solves?

When I have a scenario where I don’t want the user to directly instantiate the class but want the class to be created based on some criteria I can implement factory and the factory will take the responsibility of creating the object based on some argument received by the factory method. Also you can implement factory when you don’t know what type of related object you want to create, only during run time you will know which object to create based on some input.

How it Solves the Problem?

To solve the problem one needs a set of related classes, in this case "Car", Santro, i10 etc. There will be a base class (Product) from which all the other classes (Concrete Product) will inherit and mostly the base class will be abstract or it will be in the form of an interface. The inherited class will have the concrete implementation of the base class. Then one should have a factory class to create the related classes or you can have a base factory (Creator) from which other factories (Concrete Creator) will inherit. So this is the basic requirement to have a factory.

Real time e.g.

In .NET factory is implemented in page life cycle where “PageHandlerFactory” is used to create an ASP.NET page handler dynamically to process ASP.NET page requests. Other factory implementation in .net are “WebServiceHandlerFactory”, “SimpleHandlerFactory”, “HttpRemotingHandlerFactory” to handle, webservice, simple handlers, remoting requests respectively. Also you can find the implementation of factory in WebRequest class’ Create method, AppDomain’ CreateDomain method et all.

So with this CD was clear on Factory pattern and I hope the same is case with the reader' of this blog.

Love patterns,

Sandeep