Factory method pattern: Difference between revisions

Content deleted Content added
Rewrote article
Examples: fixed weasel word
 
(982 intermediate revisions by more than 100 users not shown)
Line 1:
The{{Short '''Factory Method pattern''' is an [[objectdescription|Object-oriented]] [[designsoftware pattern (computer science)|design pattern]].}}
In [[object-oriented programming]], the '''factory method pattern''' is a [[software design pattern|design pattern]] that uses factory methods to deal with the problem of [[object creation|creating objects]] without having to specify their exact [[class (computer programming)|classes]]. Rather than by calling a [[Constructor (object-oriented programming)|constructor]], this is accomplished by invoking a factory method to create an object. Factory methods can be specified in an [[Interface (object-oriented programming)|interface]] and implemented by subclasses or implemented in a base class and optionally [[method overriding|overridden]] by subclasses. It is one of the 23 classic design patterns described in the book ''[[Design Patterns]]'' (often referred to as the "Gang of Four" or simply "GoF") and is subcategorized as a [[creational pattern]].{{sfn|Gamma|Helm|Johnson|Vlissides|1995|page=107}}
Like other [[creational pattern]]s, it deals with the problem of [[creating]] [[object (computer science)|object]]s (products) without specifying the exact [[class (computer science)|class]] of object that will be created.
Factory Method, one of the patterns from the [[Design Patterns]] book, handles this problem by defining a separate [[method (computer science)|method]] for creating the objects, which [[subclass (computer science)|subclass]]es can then override to specify the type of product that will be created.
 
==Overview==
More generally, the term ''Factory Method'' is often used to refer to any method whose main purpose is to create objects.
The factory method design pattern solves problems such as:
* How can an object's [[Subclass (computer science)|subclasses]] redefine its subsequent and distinct implementation? The pattern involves creation of a factory method within the [[Superclass (computer science)|superclass]] that defers the object's creation to a subclass's factory method.
* How can an object's instantiation be deferred to a subclass? Create an object by calling a factory method instead of directly calling a constructor.
 
This enables the creation of subclasses that can change the way in which an object is created (for example, by redefining which class to instantiate).
 
==Definition==
According to ''[[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]]'': "Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses."<ref name="gof">{{cite book |last1=Gamma |first1=Erich |author1-link=Erich Gamma |title=Design Patterns: Elements of Reusable Object-Oriented Software |title-link=Design Patterns |last2=Helm |first2=Richard |author2-link=Richard Helm |last3=Johnson |first3=Ralph |author3-link=Ralph Johnson (computer scientist) |last4=Vlissides |first4=John |author4-link=John Vlissides |publisher=Addison-Wesley |year=1995 |isbn=0-201-63361-2}}</ref>
 
Creating an object often requires complex processes not appropriate to include within a composing object. The object's creation may lead to a significant duplication of code, may require information inaccessible to the composing object, may not provide a sufficient level of abstraction or may otherwise not be included in the composing object's [[concern (computer science)|concerns]]. The factory method design pattern handles these problems by defining a separate [[method (computer science)|method]] for creating the objects, which subclasses can then override to specify the [[Subtyping|derived type]] of product that will be created.
 
The factory method pattern relies on inheritance, as object creation is delegated to subclasses that implement the factory method to create objects.<ref>{{cite book |last1=Freeman |first1=Eric |url=http://shop.oreilly.com/product/9780596007126.do |title=Head First Design Patterns: A Brain-Friendly Guide |last2=Robson |first2=Elisabeth |last3=Sierra |first3=Kathy |last4=Bates |first4=Bert |publisher=O'Reilly Media |year=2004 |isbn=978-0-596-00712-6 |editor-last1=Hendrickson |editor-first1=Mike |edition=1st |volume=1 |page=162 |format=paperback |access-date=2012-09-12 |editor-last2=Loukides |editor-first2=Mike}}</ref>
The pattern can also rely on the implementation of an [[Interface (object-oriented programming)|interface]].
 
==Structure==
The main classes in the Factory Method pattern are the creator and the product.
The creator needs to create instances of products, but the concrete type of product should not be hardcoded in the creator &ndash; subclasses of creator should be able to specify subclasses of product to use.
 
=== UML class diagram ===
To achive this an abstract method (the factory method) is defined on the creator.
This method is defined to return a product.
Subclasses of creator can override this method to return instances of appropriate subclasses of product.
 
[[File:w3sDesign Factory Method Design Pattern UML.jpg|frame|none|A sample UML class diagram for the Factory Method design pattern.
==Example==
<ref>{{cite web|title=The Factory Method design pattern - Structure and Collaboration|url=http://w3sdesign.com/?gr=c03&ugr=struct|website=w3sDesign.com|access-date=2017-08-12}}</ref>]]
Consider a database frontend that supports many different data types.
Fields in the database are represented by class Field.
Each supported data type is mapped to a subclass of Field, for example TextField, NumberField, DateField or BooleanField.
 
In the above [[Unified Modeling Language|UML]] [[class diagram]], the <code>Creator</code> class that requires a <code>Product</code> object does not instantiate the <code>Product1</code> class directly. Instead, the <code>Creator</code> refers to a separate <code>factoryMethod()</code> to create a product object, which makes the <code>Creator</code> independent of the exact concrete class that is instantiated. Subclasses of <code>Creator</code> can redefine which class to instantiate. In this example, the <code>Creator1</code> subclass implements the abstract <code>factoryMethod()</code> by instantiating the <code>Product1</code> class.
Class field has a method display() for displaying the contents of the field on a window system.
Typically one control is created for each field, but the type of control should depend on the type of the field, for example a TextField should be displayed as a textbox, but a BooleanField should be displayed as a checkbox.
 
== Examples ==
To solve this, Field contains a factory method, createControl(), that is called from display() to get a control of the correct type.
This [[C++23]] implementation is based on the pre C++98 implementation in the ''[[Design Patterns]]'' book.{{sfn|Gamma|Helm|Johnson|Vlissides|1995|page=122}}
<syntaxhighlight lang="c++">
import std;
 
enum class ControlProductId {MINE, YOURS};
public void display() {
// ...
}
// ...
}
class TextBox : Control {
// ...
}
class CheckBox : Control {
// ...
}
abstract class Field {
public void display() {
Control c = createControl();
c.display();
}
public abstract Control createControl();
}
class TextField : Field {
private string value;
public Control createControl() {
TextBox t = new TextBox();
t.setText(this.value);
return t;
}
}
class BooleanField : Field {
private boolean value;
public Control createControl() {
CheckBox c = new CheckBox();
c.setChecked(this.value);
return c;
}
}
 
// defines the interface of objects the factory method creates.
In this case, Field is the creator, Control is the product, createControl() is the factory method, TextField and BooleanField subclass the creator and TextBox and CheckBox are subclasses of product.
class Product {
public:
virtual void print() = 0;
virtual ~Product() = default;
};
 
// implements the Product interface.
==Common usage==
class ConcreteProductMINE: public Product {
*Factory Methods are common in [[toolkit]]s and [[framework]]s where library code needs to create objects of types which may be subclassed by applications using the framework.
public:
*Parallel class hierarchies often require objects from one hierarchy to be able to create appropriate objects from another.
void print() {
std::println("this={} print MINE", this);
}
};
 
// implements the Product interface.
==Other benefits and variants==
class ConcreteProductYOURS: public Product {
Although the motivation behind the Factory Method pattern is allow subclasses to choose which type of object to create, there are other benefits to using Factory Methods, many of which don't depend on subclassing.
public:
Therefore, it is common to define "factory methods" that are not polymorphic to create objects in order to gain these other benefits. Such methods are often static.
void print() {
std::println("this={} print YOURS", this);
}
};
 
// declares the factory method, which returns an object of type Product.
===Descriptive names===
class Creator {
A factory method has a distinct name.
public:
In many object-oriented languages, constructors must have the same name as the class they are in, which can lead to ambiguity if there is more than one way to create an object.
virtual std::unique_ptr<Product> create(ProductId id) {
Factory methods have no such constraint and can have descriptive names.
if (ProductId::MINE == id) return std::make_unique<ConcreteProductMINE>();
As an example, when complex numbers are created from two real numbers the real numbers can be interpreted as cartesian or polar coordinates, but using factory methods, the meaning is clear:
if (ProductId::YOURS == id) return std::make_unique<ConcreteProductYOURS>();
// repeat for remaining products...
 
return nullptr;
class Complex {
}
public static Complex fromCartesian(double real, double imag) {
virtual ~Creator() = default;
return new Complex(real, imag);
};
}
public static Complex fromPolar(double rho, double theta) {
return new Complex(rho * cos(theta), rho * sin(theta));
}
private Complex(double a, double b) {
//...
}
}
Complex c = Complex.fromPolar(1, pi); // Same as fromCartesian(-1, 0)
 
int main() {
===Encapsulation===
// The unique_ptr prevent memory leaks.
Factory methods encapsulate the creation of objects.
std::unique_ptr<Creator> creator = std::make_unique<Creator>();
This can be useful if the creation process is complex, for example if it depends on settings in configuration files or on user input.
std::unique_ptr<Product> product = creator->create(ProductId::MINE);
product->print();
 
product = creator->create(ProductId::YOURS);
Consider as an example a program to read [[image file]]s and make [[thumbnail]]s out of them.
product->print();
The program supports different image formats, represented by a reader class for each format:
}
</syntaxhighlight>
 
The program output is like
public interface ImageReader {
public DecodedImage getDecodedImage();
}
public class GifReader implements ImageReader {
public GifReader( InputStream in ) {
// check that it's a gif, throw exception if it's not, then if it is
// decode it.
}
public DecodedImage getDecodedImage() {
return decodedImage;
}
}
public class JpegReader implements ImageReader {
//...
}
Each time the program reads an image it needs to create a reader of the appropriate type based on some information in the file.
This logic can be encapsulated in a factory method:
 
<syntaxhighlight lang="c++">
public class ImageReaderFactory {
this=0x6e5e90 print MINE
public static ImageReader getImageReader( InputStream is ) {
this=0x6e62c0 print YOURS
int imageType = figureOutImageType( is );
</syntaxhighlight>
 
switch( imageType ) {
A maze game may be played in two modes, one with regular rooms that are only connected with adjacent rooms, and one with magic rooms that allow players to be transported at random.
case ImageReaderFactory.GIF:
 
return new GifReader( is );
=== Structure ===
case ImageReaderFactory.JPEG:
[[File:New WikiFactoryMethod.png|734x734px|center]]
return new JpegReader( is );
 
// etc.
<code>Room</code> is the base class for a final product (<code>MagicRoom</code> or <code>OrdinaryRoom</code>). <code>MazeGame</code> declares the abstract factory method to produce such a base product. <code>MagicRoom</code> and <code>OrdinaryRoom</code> are subclasses of the base product implementing the final product. <code>MagicMazeGame</code> and <code>OrdinaryMazeGame</code> are subclasses of <code>MazeGame</code> implementing the factory method producing the final products. Factory methods thus decouple callers (<code>MazeGame</code>) from the implementation of the concrete classes. This makes the <code>new</code> operator redundant, allows adherence to the [[open–closed principle]] and makes the final product more flexible in the event of change.
}
 
=== Example implementations ===
====[[C Sharp (programming language)|C#]]====
 
<syntaxhighlight lang="csharp">
// Empty vocabulary of actual object
public interface IPerson
{
string GetName();
}
 
public class Villager : IPerson
{
public string GetName()
{
return "Village Person";
}
}
 
public class CityPerson : IPerson
{
public string GetName()
{
return "City Person";
}
}
 
public enum PersonType
{
Rural,
Urban
}
 
/// <summary>
/// Implementation of Factory - Used to create objects.
/// </summary>
public class PersonFactory
{
public IPerson GetPerson(PersonType type)
{
switch (type)
{
case PersonType.Rural:
return new Villager();
case PersonType.Urban:
return new CityPerson();
default:
throw new NotSupportedException();
}
}
}
</syntaxhighlight>
The above code depicts the creation of an interface called <code>IPerson</code> and two implementations called <code>Villager</code> and <code>CityPerson</code>. Based on the type passed to the <code>PersonFactory</code> object, the original concrete object is returned as the interface <code>IPerson</code>.
 
A factory method is just an addition to the <code>PersonFactory</code> class. It creates the object of the class through interfaces but also allows the subclass to decide which class is instantiated.
 
<syntaxhighlight lang="csharp">
public interface IProduct
{
string GetName();
bool SetPrice(double price);
}
 
public class Phone : IProduct
{
private double _price;
 
public string GetName()
{
return "Apple TouchPad";
}
 
public bool SetPrice(double price)
{
_price = price;
return true;
}
}
 
/* Almost same as Factory, just an additional exposure to do something with the created method */
public abstract class ProductAbstractFactory
{
protected abstract IProduct MakeProduct();
 
public IProduct GetObject() // Implementation of Factory Method.
{
return this.MakeProduct();
}
}
 
public class PhoneConcreteFactory : ProductAbstractFactory
{
protected override IProduct MakeProduct()
{
IProduct product = new Phone();
// Do something with the object after receiving it
product.SetPrice(20.30);
return product;
}
}
</syntaxhighlight>
In this example, <code>MakeProduct</code> is used in <code>concreteFactory</code>. As a result, <code>MakeProduct()</code> may be invoked in order to retrieve it from the <code>IProduct</code>. Custom logic could run after the object is obtained in the concrete factory method. <code>GetObject</code> is made abstract in the factory interface.
 
====[[Java (programming language)|Java]]====
This [[Java (programming language)|Java]] example is similar to one in the book ''[[Design Patterns]].''
 
[[File:Maze game UML.svg]]
 
The <code>MazeGame</code> uses <code>Room</code> but delegates the responsibility of creating <code>Room</code> objects to its subclasses that create the concrete classes. The regular game mode could use this template method:
 
<syntaxhighlight lang="java">
public abstract class Room {
abstract void connect(Room room);
}
 
public class MagicRoom extends Room {
public void connect(Room room) {}
}
 
public class OrdinaryRoom extends Room {
public void connect(Room room) {}
}
 
public abstract class MazeGame {
private final List<Room> rooms = new ArrayList<>();
 
public MazeGame() {
Room room1 = makeRoom();
Room room2 = makeRoom();
room1.connect(room2);
rooms.add(room1);
rooms.add(room2);
}
}
 
abstract protected Room makeRoom();
The combination of a [[type code]] and its associated specific [[factory object]] can be stored in a [[map (computer science)|map]]. The [[switch statement]] can be avoided to create an extensible factory by a [[Associative_array|mapping]].
}
</syntaxhighlight>
 
The <code>MazeGame</code> constructor is a [[Template method pattern|template method]] that adds some common logic. It refers to the <code>makeRoom()</code> factory method that encapsulates the creation of rooms such that other rooms can be used in a subclass. To implement the other game mode that has magic rooms, the <code>makeRoom</code> method may be overridden:
 
<syntaxhighlight lang="java">
public class MagicMazeGame extends MazeGame {
@Override
protected MagicRoom makeRoom() {
return new MagicRoom();
}
}
 
public class OrdinaryMazeGame extends MazeGame {
@Override
protected OrdinaryRoom makeRoom() {
return new OrdinaryRoom();
}
}
 
MazeGame ordinaryGame = new OrdinaryMazeGame();
MazeGame magicGame = new MagicMazeGame();
</syntaxhighlight>
 
====[[PHP]]====
This [[PHP]] example shows interface implementations instead of subclassing (however, the same can be achieved through subclassing). The factory method can also be defined as <code>public</code>and called directly by the client code (in contrast to the previous Java example).
 
<syntaxhighlight lang="php">
/* Factory and car interfaces */
 
interface CarFactory
{
public function makeCar(): Car;
}
 
interface Car
{
public function getType(): string;
}
 
/* Concrete implementations of the factory and car */
 
class SedanFactory implements CarFactory
{
public function makeCar(): Car
{
return new Sedan();
}
}
 
class Sedan implements Car
{
public function getType(): string
{
return 'Sedan';
}
}
 
/* Client */
 
$factory = new SedanFactory();
$car = $factory->makeCar();
print $car->getType();
</syntaxhighlight>
 
==== [[Python (programming language)|Python]] ====
This Python example employs the same as did the previous Java example.
 
<syntaxhighlight lang="python3">
from abc import ABC, abstractmethod
 
 
class MazeGame(ABC):
def __init__(self) -> None:
self.rooms = []
self._prepare_rooms()
 
def _prepare_rooms(self) -> None:
room1 = self.make_room()
room2 = self.make_room()
 
room1.connect(room2)
self.rooms.append(room1)
self.rooms.append(room2)
 
def play(self) -> None:
print(f"Playing using {self.rooms[0]}")
 
@abstractmethod
def make_room(self):
raise NotImplementedError("You should implement this!")
 
 
class MagicMazeGame(MazeGame):
def make_room(self) -> "MagicRoom":
return MagicRoom()
 
 
class OrdinaryMazeGame(MazeGame):
def make_room(self) -> "OrdinaryRoom":
return OrdinaryRoom()
 
 
class Room(ABC):
def __init__(self) -> None:
self.connected_rooms = []
 
def connect(self, room: "Room") -> None:
self.connected_rooms.append(room)
 
 
class MagicRoom(Room):
def __str__(self) -> str:
return "Magic room"
 
 
class OrdinaryRoom(Room):
def __str__(self) -> str:
return "Ordinary room"
 
 
ordinaryGame = OrdinaryMazeGame()
ordinaryGame.play()
 
magicGame = MagicMazeGame()
magicGame.play()
</syntaxhighlight>
 
==Uses==
* In [[ADO.NET]], [https://docs.microsoft.com/en-us/dotnet/api/system.data.idbcommand.createparameter?view=netframework-4.8 IDbCommand.CreateParameter] is an example of the use of factory method to connect parallel class hierarchies.
* In [[Qt (toolkit)|Qt]], [http://qt-project.org/doc/qt-5.0/qtwidgets/qmainwindow.html#createPopupMenu QMainWindow::createPopupMenu] {{Webarchive|url=https://web.archive.org/web/20150719014739/http://qt-project.org/doc/qt-5.0/qtwidgets/qmainwindow.html#createPopupMenu |date=2015-07-19 }} is a factory method declared in a framework that can be overridden in [[application code]].
* In [[Java (programming language)|Java]], several factories are used in the [http://download.oracle.com/javase/1.5.0/docs/api/javax/xml/parsers/package-summary.html javax.xml.parsers] package, such as javax.xml.parsers.DocumentBuilderFactory or javax.xml.parsers.SAXParserFactory.
* In the [[HTML5]] [[Document Object Model|DOM]] [[application programming interface|API]], the Document interface contains a createElement() factory method for creating specific elements of the HTMLElement interface.
 
==See also==
* ''[[Design Patterns]]'', the highly influential book
===Related design patterns===
* [[Design pattern]], overview of design patterns in general
*[[Abstract factory pattern|Abstract Factory]] &ndash; often implemented using Factory Methods.
* [[TemplateAbstract methodfactory pattern|Template Method]], a pattern &ndash;often mayimplemented callusing factory methods.
* [[Builder pattern]], another creational pattern
* [[Template method pattern]], which may call factory methods
* [[Joshua Bloch]]'s idea of a [[static factory method]] for which Bloch claims there is no direct equivalent in ''[[Design Patterns]]''.
 
==Notes==
{{Reflist}}
==References==
*{{Bookcite reference |book
| author1=Martin Fowler | author2-link=Kent Beck | author2=Kent Beck | author3-link=John Brant (author) | author3=John Brant | author4-link=William Opdyke | author4=William Opdyke | author5-link=Don Roberts (author) | author5=Don Roberts
Author=[[Martin Fowler|Fowler, Martin]] |
| title = Title=Refactoring: Improving the Design of Existing Code |
| publisher = Publisher=Addison-Wesley |
| date=June Year=1999 |
| isbn ID=ISBN 0-201-48567-2
| author1-link=Martin Fowler (software engineer) }}
}}
*{{cite book |author1=Cox, Brad J. |
*{{Book reference |
title=Object-oriented programming: an evolutionary approach |
Author=[[Erich Gamma|Gamma, Erich]]; [[Richard Helm|Helm, Richard]]; Johnson, Ralph; Vlissides, John |
publisher=Addison-Wesley |
Title=[[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]] |
Publisheryear=Addison-Wesley1986 |
Yearisbn=1994 |978-0-201-10393-9
ID=ISBN 0-201-63361-2|
title-link=Object-oriented programming }}
}}
*{{cite journal |
last=Cohen |
first=Tal |author2=Gil, Joseph |
title=Better Construction with Factories |
journal=Journal of Object Technology |
volume=6 |
issue=6 |
pages=103 |
year=2007 |
publisher=[[Bertrand Meyer]] |
url=http://tal.forum2.org/static/cv/Factories.pdf |
access-date=2007-03-12
|
doi=10.5381/jot.2007.6.6.a3 |
doi-access=free }}
 
==External links==
{{Wikibooks
*[http://c2.com/cgi/wiki?FactoryMethodPattern Description from the Portland Pattern Repository]
| 1 = Computer Science Design Patterns
*[http://www.refactoring.com/catalog/replaceConstructorWithFactoryMethod.html Refactoring: Replace Constructor with Factory Method]
| 2 = Factory method examples
}}
* [http://designpattern.co.il/Factory.html Factory Design Pattern] {{Webarchive|url=https://web.archive.org/web/20180110103637/http://designpattern.co.il/Factory.html |date=2018-01-10 }} Implementation in Java
 
* [https://web.archive.org/web/20080503082912/http://www.lepus.org.uk/ref/companion/FactoryMethod.xml Factory method in UML and in LePUS3] (a Design Description Language)
===Uses of Factory Method===
* [http://drdobbs.com/java/208403883 Consider static factory methods] by Joshua Bloch
*In [[ADO.NET]], [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdataidbcommandclasscreateparametertopic.asp IDbCommand.CreateParameter] is an example of the use of Factory Method to connect parallel class hierarchies.
*In [[Qt]], [http://doc.trolltech.com/4.0/qmainwindow.html#createPopupMenu QMainWindow::createPopupMenu] is a factory method declared in a framework which can be overridden in application code.
 
{{Design Patterns Patterns}}
[[Category:Software design patterns]]
 
{{DEFAULTSORT:Factory Method Pattern}}
[[de:Fabrikmethode]]
<!--Categories-->
[[Category:Software design patterns]]
[[Category:Articles with example Java code]]
[[Category:Method (computer programming)]]
[[Category:Articles with example C Sharp code]]
[[Category:Articles with example PHP code]]