Sunday 13 April 2014

Difference between the Abstract Factory and Factory Method Design Patterns - C#

    In this article we are going to see the difference between Abstract Factory and Factory Method design patterns in c#. Normally many of them thought both the design patterns are same or slightly method invocation type alone changes , True to be told that is not correct both of that patterns are totally different.
Patterns are used to make a reusable code and easy maintenance code.

Abstract Factory :
  Defines an interface for create a family of related or dependent objects with out specify the concrete class.

Factory Method :
   Defines an interface to create a object , but let the subclass or derived class to decide to which class to instantiate. 


Let we first see the Factory Method pattern, because the abstract factory is a superset.

1. Defines an Interface, that which have a method to create a object or Type.
2. Derives that interface to the Factory class and gives the implementation for that method, now derived class is a subclass which decide the what class to instantiate in that abstract method.
3. The return type of that method is a abstract type class which is derived in concrete class.

A Factory class contains the method which will create a Type at Runtime,Return Type is a Abstract class type. is Factory Method.

Now here i am creating a interface IAnimal which have a method to create animal. Factory class can derive this interface and return the  instance of each type corresponding to that factory. return type must implement a abstract class animal.

Factory Method :
**************

Interface Method:
    
    interface IAnimal
    {
        Animal CreateAnimal();

    }

Abstract Class:

  
    abstract class Animal
    {
        public int NoOfLegs { set; get; }       

       public abstract void AnimalInfo();
   
    }


concrete Class:


    class Camel:Animal
    {
        public Camel()
        {
            NoOfLegs = 4;
        }

        public override void AnimalInfo()
        {
            Console.WriteLine("Camel");
        }
    }

    class Eagel:Animal
    {
        public Eagel()
        {
            NoOfLegs = 2;
        }

        public override void AnimalInfo()
        {
            Console.WriteLine("Eagel");
        }
    }

    class Kangaroo:Animal
    {

        public Kangaroo()
        {
            NoOfLegs = 2;
        }

        public override void AnimalInfo()
        {
            Console.WriteLine("Kangaroo");
        }
    }


Factory Method:
    
   class IndianAnimalFactory:IAnimal
    {
        public Animal CreateAnimal()
        {
            return new Camel();
        }
    }

    class ForeignAnimalFactory:IAnimal
    {

        public Animal CreateAnimal()
        {
            return new Eagel();
        }
    }

    class AustraliaAnimalFactory : IAnimal
    {

        public Animal CreateAnimal()
        {
            return new Kangaroo();
        }
    }


Main class :

   class Program
    {
        static void Main(string[] args)
        {
            CreateAnimal<IndianAnimalFactory>();
            CreateAnimal<ForeignAnimalFactory>();
            CreateAnimal<AustraliaAnimalFactory>();
            Console.WriteLine();
            Console.Read();
        }

        static void CreateAnimal<T>() where T:IAnimal
        {
            T obj = Activator.CreateInstance<T>();
            Animal animalobj = obj.CreateAnimal();
            animalobj.AnimalInfo();
        }

    }

Output:

Camel
Eagel
Kangaroo




From the above sample you can see that the Factory method return the object which is decided at the subclass.

Now Let we see the Abstract Factory Design Patterns Sample.

Abstract Factory Pattern:
*********************
     For the abstract factory pattern allows to create a group of related or dependent objects.Here we will get the Factory by giving the input based on that factory is returned. Create a Concrete Products and Concrete Factory from the abstract Products , abstract factory

Abstract Factory:

    /* Abstract products */
    interface ILed
    {
        string ScreenType();
    }

    interface ILcd
    {
        string ScrennType();
    }

    /* Abstract Factory */
    interface ITVFactory
    {
        ILed CreateLEDTv();
        ILcd CreateLCDTv();
    }

   /* Concrete Factory */
    class TosibhaFactory:ITVFactory
    {

        public ILed CreateLEDTv()
        {
            return new TosibhaLED();
        }

        public ILcd CreateLCDTv()
        {
            return new ToshibaLCD();
        }
    }

    class PanasonicFactory:ITVFactory
    {

        public ILed CreateLEDTv()
        {
            return new PanasonicLED();
        }

        public ILcd CreateLCDTv()
        {
            return new PanasonicLCD();
        }
    }

    class AkaiFactory:ITVFactory
    {

        public ILed CreateLEDTv()
        {
            return new AkaiLED();
        }

        public ILcd CreateLCDTv()
        {
            return new AkaiLCD();
        }
    }

/* Concrete Products */
    class TosibhaLED:ILed
    {
        public string ScreenType()
        {
            return "Toshiba LED , LED screen";
        }
    }

    class ToshibaLCD:ILcd
    {
        public string ScrennType()
        {
            return "Toshiba LCD , LCD Screen";
        }
    }


    class PanasonicLED:ILed
    {

        public string ScreenType()
        {
            return "Panasonic LED, LED screen";
        }
    }

    class PanasonicLCD:ILcd
    {

        public string ScrennType()
        {
            return "Panasonic LCD, LCD screen";
        }
    }

    class AkaiLED:ILed
    {

        public string ScreenType()
        {
            return "Akai LED, LED Screen";
        }
    }

    class AkaiLCD:ILcd
    {

        public string ScrennType()
        {
            return "Akai LCD, LCD Screen";
        }
    }


  enum FactoryType
    {
        Akai,
        Toshiba,
        Panasonic
    }

    class TvFactory
    {
        public static ITVFactory GetFactory(FactoryType type)
        {
            switch(type)
            {
                case FactoryType.Akai:
                    return new AkaiFactory();
                case FactoryType.Panasonic:
                    return new PanasonicFactory();
                case FactoryType.Toshiba:
                    return new TosibhaFactory();
                default: return null;
            }
        }
    }

    class TvClient
    {
        ITVFactory _factory;
        ILed led;
        ILcd lcd;

        public TvClient(ITVFactory factory)
        {
            _factory = factory;
        }

        public void CreateProducts()
        {
           lcd = _factory.CreateLCDTv();
           led = _factory.CreateLEDTv();           
        }

        public void ShowProductsInformation()
        {
            Console.WriteLine(led.ScreenType());
            Console.WriteLine(lcd.ScrennType());
        }

    }


class Program
    {
        static void Main(string[] args)
        {
            ITVFactory tfactory = TvFactory.GetFactory(FactoryType.Toshiba);
            TvClient client = new TvClient(tfactory);
            client.CreateProducts();
            client.ShowProductsInformation();

            Console.WriteLine();

            tfactory = TvFactory.GetFactory(FactoryType.Panasonic);
            TvClient client2 = new TvClient(tfactory);
            client2.CreateProducts();
            client2.ShowProductsInformation();

            Console.Read();
        }     
    }

   

Output:
Toshiba LED , LED screen
Toshiba LCD , LCD Screen

Panasonic LED, LED screen

Panasonic LCD, LCD screen



From this article you can see the difference between the Abstract Factory and Factory Method.

No comments:

Post a Comment