Tuesday, February 18, 2014

Common Design Patterns in C# 4.0- Abstract Factory Pattern


Hello again ,
Last time we discussed about different Design pattern used .
Today we will learn about the Abstract Factory Pattern.

I get very good article at CodePlex 


Pattern Name:
Abstract Factory Pattern
Short Description:
Create instances of classes belonging to different families
Usage:
Very frequently used and very useful
Complexity:
1 / 5
UML Class Diagram:
image
Explanation:
  • The abstract factory class defines the abstract methods that have to be implemented by concrete factory classes. It serves as interface and contract definition.
  • The concrete factory classes contain the real implementation that define which classes are created during run-time.
  • Note that the methods return values are also defined by abstract classes, this allows a high flexibility and independence, leading to methods that must only be implemented once.
  • The returned classes are however specific to each concrete factory class (you will see their implementation below).
    public abstract class CarFactory
    {
        public abstract SportsCar CreateSportsCar();
        public abstract FamilyCar CreateFamilyCar();
    }

    public class AudiFactory : CarFactory
    {
        public override SportsCar CreateSportsCar()
        {
            return new AudiSportsCar();
        }

        public override FamilyCar CreateFamilyCar()
        {
            return new AudiFamilyCar();
        }
    }

    public class MercedesFactory : CarFactory
    {
        public override SportsCar CreateSportsCar()
        {
            return new MercedesSportsCar();
        }

        public override FamilyCar CreateFamilyCar()
        {
            return new MercedesFamilyCar();
        }
    }
  • Here you see the abstract classes that are used during the creation process (a method was added that serves to prove the validity of the design).
  • Based on the abstract classes some real example implementation are created, those will be instantiated during run-time, depending on the concrete factory that creates them.
    public abstract class SportsCar
    {
    }

    public abstract class FamilyCar
    {
        public abstract void Speed(SportsCar abstractFamilyCar);
    }

    class MercedesSportsCar : SportsCar
    {
    }
   
    class MercedesFamilyCar : FamilyCar
    {
        public override void Speed(SportsCar abstractSportsCar)
        {
            Console.WriteLine(GetType().Name + " is slower than "
                + abstractSportsCar.GetType().Name);
        }
    }

    class AudiSportsCar : SportsCar
    {
    }

    class AudiFamilyCar : FamilyCar
    {
        public override void Speed(SportsCar abstractSportsCar)
        {
            Console.WriteLine(GetType().Name + " is slower than "
                + abstractSportsCar.GetType().Name);
        }
    }
  • When implementing the associations between the Driver class, the abstract factory class and the abstract classes you may either use the common language agnostic approach using only private members (which is the most memory efficient one).
    public class Driver
    {
        private SportsCar _sportsCar;
        private FamilyCar _familyCar;

        public Driver(CarFactory carFactory)
        {
            _sportsCar = carFactory.CreateSportsCar();
            _familyCar = carFactory.CreateFamilyCar();
        }

        public void CompareSpeed()
        {
            _familyCar.Speed(_sportsCar);
        }
    }
  • Or you may use the C# language specific approach where everything is wrapped using private properties. This allows adding logic when accessing or changing the private members but might be a little overkill (this is also what gets auto-generated when modeling using the class diagram).
    public class Driver
    {
        private CarFactory _carFactory;
        private SportsCar _sportsCar;
        private FamilyCar _familyCar;

        public Driver(CarFactory carFactory)
        {
            CarFactory = carFactory;
            SportsCar = CarFactory.CreateSportsCar();
            FamilyCar = CarFactory.CreateFamilyCar();
        }

        private CarFactory CarFactory
        {
            get { return _carFactory; }
            set { _carFactory = value; }
        }

        private SportsCar SportsCar
        {
            get { return _sportsCar; }
            set { _sportsCar = value; }
        }

        private FamilyCar FamilyCar
        {
            get { return _familyCar; }
            set { _familyCar = value; }
        }

        public void CompareSpeed()
        {
            FamilyCar.Speed(SportsCar);
        }
    }
  • You may also use another C# language specific solution that uses generic classes to create objects and that is also a valid implementation for the abstract factory pattern.
    public class GenericFactory<T>
        where T : new()
    {
        public T CreateObject()
        {
            return new T();
        }
    }
  • In the last step we add some code to test the software design and the Abstract Factory implementation.
    public static void AbstractFactory()
    {
        // Language agnostic version
        CarFactory audiFactory = new AudiFactory();
        Driver driver1 = new Driver(audiFactory);
        driver1.CompareSpeed(); ;

        CarFactory mercedesFactory = new MercedesFactory();
        Driver driver2 = new Driver(mercedesFactory);
        driver2.CompareSpeed();

        // C# specific version using generics
        var factory = new GenericFactory<MercedesSportsCar>();
        var mercedesSportsCar = factory.CreateObject();
        Console.WriteLine(mercedesSportsCar.GetType().ToString());

        Console.ReadKey();
    }
  • When running the example you can see that everything is working as expected and that the correct classes are instantiated during runtime.




 try it Its one of simplest explanation i found on google


Regards
Amey 
Start where you are. Use what you have.  Do what you can.

No comments:

Post a Comment