Design Patterns In C# - Factory Design Pattern
Join the DZone community and get the full member experience.
Join For FreeSo far we have looked at the 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.
Opinions expressed by DZone contributors are their own.
Comments