Guide to Implement the Factory Pattern in C#

Introduction

This article will focus on
explaining the factory pattern in C#,
which is one of the most used patterns in the object oriented programming
world. People say that design patterns originally evolved in the civil
construction field and were later adopted in the software development field.

In simple design, patterns are
defined as the solutions to the recurring problems. These are the solutions or
program templates that were adopted and successfully implemented by the people
for some specific problems. These standard program templates or designs are
being adopted by developers to overcome similar problems. A good design pattern
makes the code clean and mandates the other programmers to follow it.

In this article I will be
including the C# language code samples for demonstration in the form of class
diagrams.

Factory Pattern

Gang of Four patterns is the famous design patterns
that are being widely followed today. Factory pattern is one among them. These
patterns are divided into three sub groups as Creational pattern, Structural
Pattern and Behavioral pattern. The factory falls under the creational pattern
category.

The factory pattern can be sub categorized into two.

  1.        Factory
    Method
  2.        Abstract
    Factory

The factory pattern is applicable
in scenarios where you don’t want the clients to decide on which of your
concrete classes to be used rather than making your code decide which of your concrete
class objects to be returned based on the parameters provided by the client.

What is Achieved by Using Factory Pattern?

  1. The object creation can be separated from the clients deciding on what objects to
    be created.
  2. The
    object creation of the concrete classes can be controlled through values such
    as:
    1. Parameters passed by the client functions.
    2. Configuration value stored in the .net
      framework
      configuration file.
    3. Configuration
      value stored in the database.
  3. Factory
    allows you to add new concrete classes and methods without breaking or
    modifying the existing code.

Factory Method

In the factory method, define an
interface for multiple factory classes and handover the object creation task to
those factory classes based. The respective factory class should be loaded then
to create the concrete objects. Below is the class diagram of the C#
application implementing the factory method pattern.

Create an interface named
ISnackFactory.

namespace FactoryMethod
{
    interface ISnackFactory
    {
        ISnack CreateSnack();
    }
}

Create two factory classes
IcecreamFactory and ChocolateFactory for creating the objects Icecream and
Chocolate respectively. Both of the concrete factories should implement from
the ISnackFactory interface.

namespace FactoryMethod
{
    class IcecreamFactory : ISnackFactory
    {
        public ISnack CreateSnack()
        {
            return new Icecream();
        }
    }
}


namespace FactoryMethod
{
    class ChocolateFactory : ISnackFactory
    {
        public ISnack CreateSnack()
        {
            return new Chocolate();
        }
    }
}
 

Create the interface called ISnack,
which should be inherited by both the concrete classes.

namespace FactoryMethod
{
    interface ISnack
    {
        bool IsRefrigirationRequired { get; }
        void Eat();
    }
}

Below are the implementations for
the concrete classes Icecream and Chocolate.

namespace FactoryMethod
{
    class Chocolate : ISnack
    {
        public bool IsRefrigirationRequired
        {
            get { return false; }
        }
 
        public void Eat()
        {
            Console.WriteLine(string.Format("Refrigiration Required? {0}", IsRefrigirationRequired));
            Console.WriteLine("Chocolate is sweet and yummy");
        }
    }
}


namespace FactoryMethod
{
    class Icecream : ISnack
    {
        public bool IsRefrigirationRequired
        {
            get { return true; }
        }
 
        public void Eat()
        {
            Console.WriteLine(string.Format("Refrigiration Required? {0}", IsRefrigirationRequired));
            Console.WriteLine("Icecream is cool and soft");
        }
    }
}

Finally add the code for the
client, which does the call to the factories and fetches the object of the
concrete class.

namespace FactoryMethod
{
    class Program
    {
        static void Main(string[] args)
        {
            ISnackFactory snackFactory = LoadFactory("icecream");

            ISnack snack = snackFactory.CreateSnack();
            snack.Eat();
        }

        private static ISnackFactory LoadFactory(string snack)
        {
            switch (snack)
            {
                case "icecream":
                    return new IcecreamFactory();

                default:
                    return new ChocolateFactory();

                    break;
            }
        }
    }
}


Figure 1

As the diagram shows, below are
the advantages and drawbacks.

  1. Since
    the objects are created by the respective factories the reference of the
    concrete classes are eliminated.
  2. The
    factories can still be inherited to make more specific objects.
  3. This
    also mandates us to create one factory just for creating the object of one
    concrete class.

Abstract Factory

Abstract factory pattern is
abstracted further that the object is created from a family or related classes
without specifying the concrete class. The client wouldn’t know which factory
will return which object from the family. Abstract factory can have multiple
factory methods each creating different types of concrete objects belonging to
the same family.

Considering the code example in
the previous section’s C# code, with the abstract factory implementation, the
Chocolate factory would know how to create a dark chocolate and milk chocolate.
For each concrete class representing a type, belonging to a family would sign
the contracts to an interface.

Conclusion

I hope this article provides an in-depth explanation of the
factory patterns and acts as a guide to the C# programmers who are striving to
implement it. Please make use of the comments section to punch in your valuable
comments.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read