What is factory pattern? where should I use?

+1 vote
asked Jun 21, 2013 in Software Practices by Dipit Kanoor

Always I have been asked about the design patterns on my interviews and most of the time it is about factory pattern. I tried to understand it by looking some articles in the internet. But could not find so far any article explains about factory pattern with simple and complete explanation. can some explain me how and where to use this design pattern in VB.NET?

Share

1 Answer

+1 vote
answered Jun 22, 2013 by Aadhira (1,213 points)
selected Jun 25, 2013 by administrator
 
Best answer

In object oriented programming, whenever you want to access methods, properties or any members of an instance class, we need create object of that particular class. Using the instance of that class only, we can interact with that class. But creating the instance can be done from different places. Usually, we will do it from the calling class. But there are some design patterns which help us to create the instances in a better way to achieve some best practices in software development. In that list, Factory Pattern is one of the pattern. In this answer, I have explained, Simple Factory Pattern and Factory Method Pattern.

Simple Factory Pattern
The concept behind the Factory pattern is to creating instance of the concrete classes should be separated from the calling class. That should be the responsibility of the factory. Also, factory should return the interface not the concrete class.

So, when should you use Factory Pattern?
If the application has to find the concrete class during runtime, to work with, based on some particular condition or the parameter passed by the calling function,
If you creates instance of concrete classes based on if and else condition
If you creating instance based on the switch condition

What are the benefits by using this design pattern?
Separates the instance creation of concrete classes, from the client which uses that class.
Allows achieving Solid principles of software like Single Responsibility Principle, Open Close Principle.
Giving the extensibility to add new class without affecting the existing classes.
Allows writing unit testing for each classes by creating fake classes to test the functionality.
Allows achieving separation of concern

Please look at the below example, where we are creating instances of the concrete classes, based on the value passed by the user.The code may look very simple, but we are violating the open close principle. Because, if you need to add a new shape, we need to modify this if condition. But, as per the open close principle, a class should be modified only for extension, not for modification.

class Program
 {
    static void Main(string[] args)
    {
        Console.WriteLine("Please type any one option from below list");
        Console.WriteLine("Square");
        Console.WriteLine("Rectangle");
        string option = Console.ReadLine();

        if (!String.IsNullOrEmpty(option))
        {
            if (option.ToLower() == "square")
            {
                Square square = new Square();
                Console.WriteLine(square.Area());
            }
            else if(option.ToLower() == "rectangle")
            {
                Rectangle rectangle = new Rectangle();
                Console.WriteLine(rectangle.Area());
            }
        }

       Console.Read();
    }
}
public class Square
{
    public string Area() { return "Square area calculated..."; }
}
public class Rectangle
{
    public string Area() { return "Rectangle area calculated..."; }
}

Simple Factory Pattern will help us to resolve this issue. In Simple Factory Pattern, Factory (SimpleShapeFactory) is a concrete class. It does not implement any interface. But, there will be a common interface (IShape), implemented by all the concrete classes (Square, Rectangle and Triangle) with which the client (Console Application) wanted to work with. So, when the Factory finds the matching class, it will return the instance of type implemented interface (IShape).

Once the class implements IShape, we are making sure that the class has a method (Area) with same name and signature as we have in interface(IShape).

How Factory finds the concrete class?
Factory will be using reflection concept (This is not the only way to find the concrete instance) to find the matching concrete class. What it does is, it will go through the current executing assembly and check each and every class which is implementing IShape interface also the class name should match with the value passed to the Factory.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Please type any one option from below list");
        Console.WriteLine("Square");
        Console.WriteLine("Rectangle");
        string option = Console.ReadLine();
        IShape shape = new SimpleShapeFactory().GetInstance(option);
        Console.WriteLine(shape.Area());
        Console.Read();
    }
}

public interface IShape
{
    string Area();
}

public class Square : IShape
{
    public string Area() { return "Square area calculated..."; }
}

public class Rectangle : IShape
{
    public string Area() { return "Rectangle area calculated...";}
}

public class SimpleShapeFactory
{
     public IShape GetInstance(string shape)
     {
          Type matchedShape = Assembly.GetExecutingAssembly().GetTypes().ToList().Where(x => x.IsClass && x.GetInterface("IShape") != null && x.Name.ToString().ToLower() == shape.ToLower()).FirstOrDefault();

          if (matchedShape != null)
          {
              return (IShape)Activator.CreateInstance(matchedShape);
          }
          return new NoShape();
    }
}

Factory Method Pattern:
Factory method pattern is almost same as Simple Factory Pattern. The difference is, Factory will not just be a concrete class, but also implement an interface. The interface will have a method that will be called by the calling class. So, there will be multiple Factory classes which do know how to create its sub class. But, this factory will know how to create instance for only one sub class. (This is the main difference between Factory Method Pattern and Abstract Factory Pattern) So calling class will get the right factory first and the factory will create the instance of subclass.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Please type any one option from below list");
        Console.WriteLine("Square");
        Console.WriteLine("Rectangle");
        string option = Console.ReadLine();
        IShapeFactory shapeFactory = LoadFactory(option);
        IShape shape = shapeFactory.CreateShape();
        Console.WriteLine(shape.Area());
        Console.Read();
    }

    private static IShapeFactory LoadFactory(string shape)
    {
        Type matchedShape = Assembly.GetExecutingAssembly().GetTypes().ToList().Where(x => x.IsClass && x.GetInterface("IShapeFactory") != null && x.Name.ToString().ToLower() == shape.ToLower() + "factory").FirstOrDefault();

        if (matchedShape != null)
        {
            return (IShapeFactory)Activator.CreateInstance(matchedShape);
        }
        return new NoShapeFactory();
    }
}
public interface IShapeFactory
{
    IShape CreateShape();
}
public class SquareFactory : IShapeFactory
{
    public IShape CreateShape() { return new Square(); }
}
public class RectangleFactory : IShapeFactory
{
    public IShape CreateShape() { return new Rectangle(); }
}

If you use any of these pattern, when you need add a new shape like Circle, all you need to do is, just to add a new class for Circle, implement IShape, and provide the option for the user.

Note:
With the way we implemented out code in Factory to identify the shape class, we need to make sure the option what we provide for the use should match with the class name. Because, that is one of the condition added in factory to find the shape. You can use some different method to resolve this issue.

Your answer

Preview

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
Anti-spam verification:
To avoid this verification in future, please log in or register.
site design / logo / content © 2013 - 2015 pinfaq.com
...