Over a million developers have joined DZone.

Design Patterns In C# - Factory Design Pattern

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

So far we have looked at the Singleton Design Pattern and the Prototype Design Pattern, now we're going to look at the Factory Design Pattern and how we can implement it in C#.


What is it:


The Factory Design Pattern is a Creational Pattern. The official definition for the Factory pattern is:


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


This pattern is used to replace a class constructor(s), allowing the type of object to be instantiated to be determined at run-time as opposed to design-time, and is used to control a class’s instantiation. The use of this design pattern reduces the coupling between classes, and offers much more flexibility in the future if the requirements of your application changes, which often happens. One tangible benefit of the Factory pattern is it allows the client to focus on its role in the architecture because it allows for separation the creation & instantiation of objects from the client.


Implementation:


To implement the Factory design pattern we will create an Interface which will define the classes that will be instantiated by our factory class. Here we're using a very simple example but know this is a very powerful design pattern and can be expanded to more complex structures & objects. So, for this we will have an interface (IEmployee) that has a single value, Salary that all our objects will implement (keep in mind this is just an example to show how this design pattern works and can be implemented):

using System;namespace DZoneArticles.FactoryDesignPattern{    public interface IEmployee    {        double Salary { get; }    }}

Now we have 3 classes (factory objects) to demonstrate different employee types. We have Manager, Programmer, and DBA which all implement our IEmployee interface, utilizing a single read-only property:


Manager:

using System;namespace DZoneArticles.FactoryDesignPattern{    public class Manager : IEmployee    {        public double Salary        {            get { return 75.5; }        }    }}

Programmer:

using System;namespace DZoneArticles.FactoryDesignPattern{    public class Programmer : IEmployee    {        public double Salary        {            get { return 70.5; }        }    }}

DBA:

using System;namespace DZoneArticles.FactoryDesignPattern{    public class DBA : IEmployee    {        public double Salary        {            get { return 69.5; }        }    }}

Now we need a factory class to handle the instantiation of our factory objects. Although in our example our factory manager class only has a single method (factory method), this method completely encapsulates the creation of our factory objects. Our factory method is declared as static so no instance our the factory manager need be made:

using System;namespace DZoneArticles.FactoryDesignPattern{    public class EmployeeFactory    {        public enum EmployeeType        {            ManagerType,            ProgrammerType,            DBAType        }        public static IEmployee GetEmployeeSalary(EmployeeType type)        {            IEmployee employee = null;            switch (type)            {                case EmployeeType.ManagerType:                    employee = new Manager();                    break;                case EmployeeType.ProgrammerType:                    employee = new Programmer();                    break;                case EmployeeType.DBAType:                    employee = new DBA();                    break;                default:                    throw new ArgumentException(string.Format("An employee of type {0} cannot be found", Enum.GetName(typeof(EmployeeType), type)));            }            return employee;        }    }}

Ok we now have our factory defined and created, so how do I use it you may ask, well I'll show you. We will generate a new employee for each class in a loop using the factory manager class, then print out each salary. This is done without the client ever knowing what object type is being instantiated, and this is because our factory class handles the instantiation of any employee type that is created:

static void Main(string[] args){    Dictionary<EmployeeFactory.EmployeeType, IEmployee> employees = new Dictionary<EmployeeFactory.EmployeeType, IEmployee>();    //let's create a new employee for each available employee type. Each item is insatantiated    //without the client needing to know what type of object is being created (this is handled by the factory method)    foreach (EmployeeFactory.EmployeeType e in Enum.GetValues(typeof(EmployeeFactory.EmployeeType)))    {        employees.Add(e, EmployeeFactory.GetEmployeeSalary(e));    }    //now let's iterate through our dictionary and diplay the base salary for each factory object    foreach (EmployeeFactory.EmployeeType type in employees.Keys)        Console.WriteLine(string.Format("The base salary for {0} is {1:C}", type, employees[type].Salary));        Console.ReadKey();}

Well that is how the Factory Design Pattern works and is used, as you can see if can be extremely powerful and helpful (especially when dealing with complex creation processes, such as when the creation depends on input from the user or from some sort of configuration file) when designing complex software. Thanks for reading and hope you found it useful & informative.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:
dotnet ,c# ,c-sharp ,c# design patterns

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}