Factory Method Design Pattern
 |
Define an interface for creating an object, but let subclasses decide which class to
instantiate. Factory Method lets a class defer instantiation to subclasses.
Frequency of use: high
|
|
 |
The classes and/or objects participating in this pattern are:
- Product (Page)
- defines the interface of objects the factory method creates
- ConcreteProduct (SkillsPage, EducationPage, ExperiencePage)
- implements the Product interface
- Creator (Document)
- declares the factory method, which
returns an object of type Product. Creator may also define a
default implementation of the factory method that returns a
default ConcreteProduct object.
- may call the factory method to create a Product object.
- ConcreteCreator (Report, Resume)
- overrides the factory method to return an instance of a ConcreteProduct.
This structural code demonstrates the Factory method offering great flexibility in creating
different objects. The Abstract class may provide a default object, but
each subclass can instantiate an extended version of the object.
Show code
|
// Factory Method pattern -- Structural example
|
|
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Factory.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// An array of creators
Creator[] creators = new Creator[2];
creators[0] = new ConcreteCreatorA();
creators[1] = new ConcreteCreatorB();
// Iterate over creators and create products
foreach(Creator creator in creators)
{
Product product = creator.FactoryMethod();
Console.WriteLine("Created {0}",
product.GetType().Name);
}
// Wait for user
Console.Read();
}
}
// "Product"
abstract class Product
{
}
// "ConcreteProductA"
class ConcreteProductA : Product
{
}
// "ConcreteProductB"
class ConcreteProductB : Product
{
}
// "Creator"
abstract class Creator
{
public abstract Product FactoryMethod();
}
// "ConcreteCreator"
class ConcreteCreatorA : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductA();
}
}
// "ConcreteCreator"
class ConcreteCreatorB : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductB();
}
}
}
|
Output
Created ConcreteProductA
Created ConcreteProductB
|
This real-world code demonstrates the Factory method offering flexibility in creating
different documents. The derived Document classes Report and Resume instantiate extended
versions of the Document class. Here, the Factory Method is called in the constructor
of the Document base class.
Show code
|
// Factory Method pattern -- Real World example
|
|
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Factory.RealWorld
{
// MainApp test application
class MainApp
{
static void Main()
{
// Note: constructors call Factory Method
Document[] documents = new Document[2];
documents[0] = new Resume();
documents[1] = new Report();
// Display document pages
foreach (Document document in documents)
{
Console.WriteLine("\n" + document.GetType().Name+ "--");
foreach (Page page in document.Pages)
{
Console.WriteLine(" " + page.GetType().Name);
}
}
// Wait for user
Console.Read();
}
}
// "Product"
abstract class Page
{
}
// "ConcreteProduct"
class SkillsPage : Page
{
}
// "ConcreteProduct"
class EducationPage : Page
{
}
// "ConcreteProduct"
class ExperiencePage : Page
{
}
// "ConcreteProduct"
class IntroductionPage : Page
{
}
// "ConcreteProduct"
class ResultsPage : Page
{
}
// "ConcreteProduct"
class ConclusionPage : Page
{
}
// "ConcreteProduct"
class SummaryPage : Page
{
}
// "ConcreteProduct"
class BibliographyPage : Page
{
}
// "Creator"
abstract class Document
{
private ArrayList pages = new ArrayList();
// Constructor calls abstract Factory method
public Document()
{
this.CreatePages();
}
public ArrayList Pages
{
get{ return pages; }
}
// Factory Method
public abstract void CreatePages();
}
// "ConcreteCreator"
class Resume : Document
{
// Factory Method implementation
public override void CreatePages()
{
Pages.Add(new SkillsPage());
Pages.Add(new EducationPage());
Pages.Add(new ExperiencePage());
}
}
// "ConcreteCreator"
class Report : Document
{
// Factory Method implementation
public override void CreatePages()
{
Pages.Add(new IntroductionPage());
Pages.Add(new ResultsPage());
Pages.Add(new ConclusionPage());
Pages.Add(new SummaryPage());
Pages.Add(new BibliographyPage());
}
}
}
|
Output
Resume -------
SkillsPage
EducationPage
ExperiencePage
Report -------
IntroductionPage
ResultsPage
ConclusionPage
SummaryPage
BibliographyPage
|
This .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features.
Show code
|
// Factory Method pattern -- .NET optimized
|
See our Singleton page for a .NET optimized code sample.
|
|
|