The factory method pattern deals with the problem of creating objects without specifying the exact class of object that will be created.
The factory method design pattern handles this problem by defining a separate method for creating the objects, whose subclasses can then override to specify the derived type that will be created.
More generally, the term factory method is often used to refer to any method whose main purpose is creation of objects.
Code examples (click to enlarge/collapse):
-
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162using System;namespace HvD.FactoryMethod{class Program{static void Main(string[] args){// Pesky user interfaceConsole.WriteLine("Choose a product:");Console.WriteLine("1) Concrete Product 1");Console.WriteLine("2) Concrete Product 2");int input = int.Parse(Console.ReadLine());// the real stuffCreator creator = new ConcreteCreator();Product product = creator.FactoryMethod(input);string productName = product.ProductName;//Console.WriteLine("Product name = {0}", productName);Console.ReadKey();}}public abstract class Product{protected string m_ProductName = "BaseProduct";public string ProductName{get { return m_ProductName; }set { m_ProductName = value; }}}public class ConcreteProduct1 : Product{public ConcreteProduct1(){m_ProductName = "ConcreteProduct1";}}public class ConcreteProduct2 : Product{public ConcreteProduct2(){m_ProductName = "ConcreteProduct2";}}public abstract class Creator{public abstract Product FactoryMethod(int ProductType);}public class ConcreteCreator : Creator{public override Product FactoryMethod(int ProductType){switch (ProductType){case 1:return new ConcreteProduct1();case 2:return new ConcreteProduct2();default:return null;}}}}
-
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071using System;namespace HvD.FactoryMethod{class Program{static void Main(string[] args){// Pesky user interfaceConsole.WriteLine("Enter your full name:");string fullname = Console.ReadLine();// the real stuffCreator creator = new NamerCreator();Namer namer = creator.CreateNamer(fullname);string firstName = namer.FirstName;string lastName = namer.LastName;//Console.WriteLine("First name = {0}", firstName);Console.WriteLine("Last name = {0}", lastName);Console.ReadKey();}}public abstract class Creator{public abstract Namer CreateNamer(string fullname);}public class NamerCreator : Creator{public override Namer CreateNamer(string fullname){if (fullname.IndexOf(',') < 0){return new FirstNameFirst(fullname);}else{return new LastNameFirst(fullname);}}}public abstract class Namer{protected string m_FirstName = null;public string FirstName{get { return m_FirstName; }set { m_FirstName = value; }}protected string m_LastName = null;public string LastName{get { return m_LastName; }set { m_LastName = value; }}}public class FirstNameFirst : Namer{public FirstNameFirst(string fullname){int index = fullname.IndexOf(' ');m_FirstName = fullname.Substring(0, index);m_LastName = fullname.Substring(index + 1);}}public class LastNameFirst : Namer{public LastNameFirst(string fullname){int index = fullname.IndexOf(',');m_FirstName = fullname.Substring(index + 2);m_LastName = fullname.Substring(0, index);}}}
The real world example is my favourite example using a Namer factory class. Depending on how you provide your full name (First-Name-First or Last-Name-First) your first name and last name are extracted from your full name. Using this pattern you can easily add other name patterns, for example how to handle middle names.
With this foundation you should be able to successfully implement the Factory Method Pattern.
This post is part of my series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern and look at simplified real-world C# code that implements the pattern.
Comments