Factory method pattern: Difference between revisions

Content deleted Content added
No edit summary
Tags: Reverted possible vandalism references removed Disambiguation links added
Examples: fixed weasel word
 
(27 intermediate revisions by 18 users not shown)
Line 1:
{{Short description|Object-oriented software design pattern}}
[[Image:FactoryMethod.svg|thumb|right|300px|Factory method in [[Unified Modeling Language|UML]]]]
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}}
[[Image:Factory Method pattern in LePUS3.png|thumb|right|300px|Factory Method in [[Lepus3|LePUS3]]]]
The '''factory method pattern''' is an [[object-oriented]] [[design pattern (computer science)|design pattern]] to implement the concept of [[factory (software concept)|factories]].
 
==Overview==
Like other [[creational pattern]]s, it deals with the problem of creating [[object (computer science)|objects]] (products) without specifying the exact [[class (computer science)|class]] of object that will be created.
The factory method design pattern solves problems such as:
The factory method design pattern handles this problem by defining a separate [[method (computer science)|method]] for creating the objects, which [[subclass (computer science)|subclasses]] can then override to specify the [[derived type]] of product that will be created.
* 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).
Outside the scope of design patterns, the term ''factory method'' can also refer to a method of a [[factory (software concept)|factory]] whose main purpose is creation of objects.
 
==Definition==
TheAccording essenceto of''[[Design thePatterns|Design FactoryPatterns: methodElements Patternof isReusable toObject-Oriented Software]]'': "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."<ref name="gof">Gang{{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 Of|year=1995 Four|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.
==Common usage==
Factory methods are common in [[toolkit]]s and [[Software framework|frameworks]] where library code needs to create objects of types which may be subclassed by applications using the framework.
 
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>
Parallel class hierarchies often require objects from one hierarchy to be able to create appropriate objects from another.
The pattern can also rely on the implementation of an [[Interface (object-oriented programming)|interface]].
 
==Structure==
Factory methods are used in [[test-driven development]] to allow classes to be put under test<ref>{{cite book
|author=[[Michael Feathers|Feathers, Michael]]
|isbn=978-0131177055
|title=Working Effectively with Legacy Code
|date=October 2004
|publisher=Prentice Hall Professional Technical Reference
|___location=Upper Saddle River, NJ
}}</ref>. If such a class <code>Foo</code> creates another object <code>Dangerous</code> that can't be put under automated [[unit test]]s (perhaps it communicates with a production database that isn't always available), then the creation of <code>Dangerous</code> objects is placed in the [[virtual function|virtual]] factory method <code>createDangerous</code> in class <code>Foo</code>. For testing, <code>TestFoo</code> (a subclass of <code>Foo</code>) is then created, with the virtual factory method <code>createDangerous</code> overridden to create and return <code>FakeDangerous</code>, a [[fake object]]. Unit tests then use <code>TestFoo</code> to test the functionality of <code>Foo</code> without incurring the side effect of using a real <code>Dangerous</code> object.
 
==Other= benefitsUML andclass variantsdiagram ===
Although the motivation behind the factory method pattern is to allow subclasses to choose which type of object to create, there are other benefits to using factory methods, many of which do not depend on subclassing.
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.
 
[[File:w3sDesign Factory Method Design Pattern UML.jpg|frame|none|A sample UML class diagram for the Factory Method design pattern.
===Descriptive names===
<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>]]
A factory method has a distinct name. In many object-oriented languages, [[constructor (computer science)|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 (see [[polymorphism (computer science)#Overloading|overloading]]). Factory methods have no such constraint and can have descriptive names. As an example, when [[complex number]]s 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 (the following examples are in [[Java (programming language)|Java]]):
<source lang="java">
class Complex
{
public static Complex fromCartesian(double real, double imag) {
return new Complex(real, imag);
}
public static Complex fromPolar(double modulus, double angle) {
return new Complex(modulus * cos(angle), modulus * sin(angle));
}
private Complex(double a, double b) {
//...
}
}
Complex c = Complex.fromPolar(1, pi);
</source>
When factory methods are used for disambiguation like this, the constructor is often made private to force clients to use the factory methods.
 
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.
===Encapsulation===
Factory methods encapsulate the creation of objects.
This can be useful if the creation process is very complex, for example if it depends on settings in configuration files or on user input.
 
== Examples ==
Consider as an example a program to read [[image file]]s and make [[thumbnail]]s out of them.
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}}
The program supports different image formats, represented by a reader class for each format:
<sourcesyntaxhighlight lang="javac++">
import std;
public interface ImageReader {
public DecodedImage getDecodedImage();
}
public class GifReader implements ImageReader {
public DecodedImage getDecodedImage() {
return decodedImage;
}
}
public class JpegReader implements ImageReader {
// ....
}
</source>
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:
<source lang="java">
public class ImageReaderFactory {
public static ImageReader getImageReader(InputStream is) {
int imageType = determineImageType(is);
 
enum class ProductId {MINE, YOURS};
switch(imageType) {
case ImageReaderFactory.GIF:
return new GifReader(is);
case ImageReaderFactory.JPEG:
return new JpegReader(is);
// etc.
}
}
}
</source>
 
The code fragment in the previous example uses a [[switch statement]] to associate an <code>imageType</code> with a specific [[factory object]]. Alternatively, this association could also be implemented as a [[map (computer science)|mapping]]. This would allow the switch statement to be replaced with an [[associative array]] lookup.
 
==Limitations==
There are three limitations associated with the use of the factory method. The first relates to [[code refactoring|refactoring]] existing code; the other two relate to extending a class.
 
* The first limitation is that refactoring an existing class to use factories breaks existing clients. For example, if class Complex was a standard class, it might have numerous clients with code like:
 
<source lang="java">Complex c = new Complex(-1, 0);</source>
 
:Once we realize that two different factories are needed, we change the class (to the code shown earlier). But since the constructor is now private, the existing client code no longer compiles.
 
* The second limitation is that, since the pattern relies on using a private constructor, the class cannot be extended. Any subclass must invoke the inherited constructor, but this cannot be done if that constructor is private.
 
* The third limitation is that, if we do extend the class (e.g., by making the constructor protected -- this is risky but possible), the subclass must provide its own re-implementation of all factory methods with exactly the same signatures. For example, if class StrangeComplex extends Complex, then unless StrangeComplex provides its own version of all factory methods, the call StrangeComplex.fromPolar(1, pi) will yield an instance of ''Complex'' (the superclass) rather than the expected instance of the subclass.
 
All three problems could be alleviated by altering the underlying programming language to make factories first-class class members (see also [[Virtual class]]). <ref>{{cite journal
|fist=Ellen
|last=Agerbo
|first=Aino
|coauthors=Agerbo, Cornils
|isbn=1-58113-005-8
|title=How to preserve the benefits of design patterns
|pages=134–143
|year=1998
|journal=Conference on Object Oriented Programming Systems Languages and Applications
|___location=Vancouver, British Columbia, Canada
|publisher=ACM
}}</ref>
 
==Example==
 
=== ABAP ===
<source lang="abap">
REPORT zz_pizza_factory_test NO STANDARD PAGE HEADING .
 
TYPES ty_pizza_type TYPE i .
 
*----------------------------------------------------------------------*
* CLASS lcl_pizza DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_pizza DEFINITION ABSTRACT .
 
PUBLIC SECTION .
 
DATA p_pizza_name TYPE string .
 
METHODS get_price ABSTRACT
RETURNING value(y_price) TYPE i .
 
ENDCLASS . "lcl_pizza DEFINITION
 
*----------------------------------------------------------------------*
* CLASS lcl_ham_and_mushroom_pizza DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_ham_and_mushroom_pizza DEFINITION INHERITING FROM lcl_pizza .
 
PUBLIC SECTION .
 
METHODS constructor .
METHODS get_price REDEFINITION .
 
ENDCLASS . "lcl_ham_and_mushroom_pizza DEFINITION
 
*----------------------------------------------------------------------*
* CLASS lcl_deluxe_pizza DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_deluxe_pizza DEFINITION INHERITING FROM lcl_pizza .
 
PUBLIC SECTION .
 
METHODS constructor .
METHODS get_price REDEFINITION .
 
ENDCLASS . "lcl_ham_and_mushroom_pizza DEFINITION
 
*----------------------------------------------------------------------*
* CLASS lcl_hawaiian_pizza DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_hawaiian_pizza DEFINITION INHERITING FROM lcl_pizza .
 
PUBLIC SECTION .
 
METHODS constructor .
METHODS get_price REDEFINITION .
 
ENDCLASS . "lcl_ham_and_mushroom_pizza DEFINITION
 
*----------------------------------------------------------------------*
* CLASS lcl_pizza_factory DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_pizza_factory DEFINITION .
PUBLIC SECTION .
 
CONSTANTS: BEGIN OF co_pizza_type ,
ham_mushroom TYPE ty_pizza_type VALUE 1 ,
deluxe TYPE ty_pizza_type VALUE 2 ,
hawaiian TYPE ty_pizza_type VALUE 3 ,
END OF co_pizza_type .
 
 
CLASS-METHODS create_pizza IMPORTING x_pizza_type TYPE ty_pizza_type
RETURNING value(yo_pizza) TYPE REF TO lcl_pizza
EXCEPTIONS ex_invalid_pizza_type .
 
 
ENDCLASS . "lcl_pizza_factory DEFINITION
 
*----------------------------------------------------------------------*
* CLASS lcl_ham_and_mushroom_pizza
*----------------------------------------------------------------------*
CLASS lcl_ham_and_mushroom_pizza IMPLEMENTATION .
 
METHOD constructor .
super->constructor( ) .
p_pizza_name = 'Ham & Mushroom Pizza'(001) .
ENDMETHOD . "constructor
 
METHOD get_price .
y_price = 850 .
ENDMETHOD . "get_price
 
ENDCLASS . "lcl_ham_and_mushroom_pizza IMPLEMENTATION
 
*----------------------------------------------------------------------*
* CLASS lcl_deluxe_pizza IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_deluxe_pizza IMPLEMENTATION .
 
METHOD constructor .
super->constructor( ) .
p_pizza_name = 'Deluxe Pizza'(002) .
ENDMETHOD . "constructor
 
METHOD get_price .
y_price = 1050 .
ENDMETHOD . "get_price
 
ENDCLASS . "lcl_deluxe_pizza IMPLEMENTATION
 
*----------------------------------------------------------------------*
* CLASS lcl_hawaiian_pizza IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_hawaiian_pizza IMPLEMENTATION .
 
METHOD constructor .
super->constructor( ) .
p_pizza_name = 'Hawaiian Pizza'(003) .
ENDMETHOD . "constructor
 
METHOD get_price .
y_price = 1150 .
ENDMETHOD . "get_price
 
ENDCLASS . "lcl_hawaiian_pizza IMPLEMENTATION
 
*----------------------------------------------------------------------*
* CLASS lcl_pizza_factory IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_pizza_factory IMPLEMENTATION .
 
METHOD create_pizza .
 
CASE x_pizza_type .
WHEN co_pizza_type-ham_mushroom .
CREATE OBJECT yo_pizza TYPE lcl_ham_and_mushroom_pizza .
WHEN co_pizza_type-deluxe .
CREATE OBJECT yo_pizza TYPE lcl_deluxe_pizza .
WHEN co_pizza_type-hawaiian .
CREATE OBJECT yo_pizza TYPE lcl_hawaiian_pizza .
ENDCASE .
 
ENDMETHOD . "create_pizza
 
ENDCLASS . "lcl_pizza_factory IMPLEMENTATION
 
 
START-OF-SELECTION .
 
DATA go_pizza TYPE REF TO lcl_pizza .
DATA lv_price TYPE i .
 
DO 3 TIMES .
 
go_pizza = lcl_pizza_factory=>create_pizza( sy-index ) .
lv_price = go_pizza->get_price( ) .
WRITE:/ 'Price of', go_pizza->p_pizza_name, 'is £', lv_price LEFT-JUSTIFIED .
 
ENDDO .
 
*Output:
*Price of Ham & Mushroom Pizza is £ 850
*Price of Deluxe Pizza is £ 1.050
*Price of Hawaiian Pizza is £ 1.150
 
</source>
 
 
=== ActionScript 3.0 ===
<source lang="actionscript">
public class Pizza {
protected var _price:Number;
public function get price():Number {
return _price;
}
}
 
public class HamAndMushroomPizza extends Pizza {
public function HamAndMushroomPizza() {
_price = 8.5;
}
}
 
public class DeluxePizza extends Pizza {
public function DeluxePizza() {
_price = 10.5;
}
}
 
public class HawaiianPizza extends Pizza {
public function HawaiianPizza() {
_price = 11.5;
}
}
 
public class PizzaFactory {
static public function createPizza(type:String):Pizza {
switch (type) {
case "HamAndMushroomPizza":
return new HamAndMushroomPizza();
break;
case "DeluxePizza":
return new DeluxePizza();
break;
case "HawaiianPizza":
return new HawaiianPizza();
break;
default:
throw new ArgumentError("The pizza type " + type + " is not recognized.");
}
}
}
 
public class Main extends Sprite {
public function Main() {
for each (var pizza:String in ["HamAndMushroomPizza", "DeluxePizza", "HawaiianPizza"]) {
trace("Price of " + pizza + " is " + PizzaFactory.createPizza(pizza).price);
}
}
}
 
Output:
Price of HamAndMushroomPizza is 8.5
Price of DeluxePizza is 10.5
Price of HawaiianPizza is 11.5
</source>
 
===C++===
<source lang="cpp">
C++ Example:
 
#include <string>
#include <iostream>
 
// defines the interface of objects the factory method creates.
class Document {
class Product {
private:
char name[25];
public:
virtual void print() = 0;
Document(char *nm)
virtual ~Product() = default;
{
strcpy(name,nm);
}
char *getName()
{
return name;
}
virtual void Open()=0;
virtual void Close()=0;
};
 
// implements the Product interface.
class View {
class ConcreteProductMINE: public Product {
private:
char name[25];
public:
void print() {
View(char *nm)
std::println("this={} print MINE", this);
{
}
strcpy(name,nm);
}
virtual void Init()=0;
virtual void Draw()=0;
};
 
// implements the Product interface.
class Application {
class ConcreteProductYOURS: public Product {
public:
void print() {
Document* newDocument(char *nm)
std::println("this={} print YOURS", this);
{
}
return createDocument(nm);
}
View* newView(char *nm)
{
return createView(nm);
}
virtual Document* createDocument(char *)=0;
virtual View* createView(char *)=0;
};
 
// declares the factory method, which returns an object of type Product.
// application specific class, which use the framework
class Creator {
 
class HelloDocument : public Document {
public:
virtual std::unique_ptr<Product> create(ProductId id) {
HelloDocument(char *nm):Document(nm)
if (ProductId::MINE == id) return std::make_unique<ConcreteProductMINE>();
{
if (ProductId::YOURS == id) return std::make_unique<ConcreteProductYOURS>();
// repeat for remaining products...
 
return nullptr;
}
}
void Open()
virtual ~Creator() = default;
{
cout << "\n\tOpening the hello document";
}
void Close()
{
cout << "\n\tClosing the hello document";
}
};
 
int main() {
class HelloView : public View {
// The unique_ptr prevent memory leaks.
public:
std::unique_ptr<Creator> creator = std::make_unique<Creator>();
HelloView(char *nm):View(nm)
std::unique_ptr<Product> product = creator->create(ProductId::MINE);
{
product->print();
 
product = creator->create(ProductId::YOURS);
}
product->print();
void Init()
}
{
</syntaxhighlight>
cout << "\n\tInitializing the hello view";
}
void Draw()
{
cout << "\n\tDrawing in hello view";
}
};
 
The program output is like
class HelloApplication : public Application {
public:
Document* createDocument(char *nm)
{
return new HelloDocument(nm);
}
View* createView(char *nm)
{
return new HelloView(nm);
}
};
 
<syntaxhighlight lang="c++">
this=0x6e5e90 print MINE
this=0x6e62c0 print YOURS
</syntaxhighlight>
 
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.
int main()
{
HelloApplication happ;
HelloDocument *pDoc = (HelloDocument *)happ.newDocument("hello doc");
HelloView *pView = (HelloView *)happ.newView("abc");
 
=== Structure ===
}
[[File:New WikiFactoryMethod.png|734x734px|center]]
</source>
 
<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.
=== C# ===
<source lang="csharp">
 
=== Example implementations ===
public interface IPizza
====[[C Sharp (programming language)|C#]]====
 
<syntaxhighlight lang="csharp">
// Empty vocabulary of actual object
public interface IPerson
{
decimalstring Price { getGetName(); }
}
 
public class HamAndMushroomPizzaVillager : IPizzaIPerson
{
public string GetName()
decimal IPizza.Price
{
getreturn "Village Person";
{
return 8.5m;
}
}
}
 
public class DeluxePizzaCityPerson : IPizzaIPerson
{
public string GetName()
decimal IPizza.Price
{
getreturn "City Person";
{
return 10.5m;
}
}
}
 
public classenum HawaiianPizza : IPizzaPersonType
{
Rural,
decimal IPizza.Price
Urban
}
 
/// <summary>
/// Implementation of Factory - Used to create objects.
/// </summary>
public class PersonFactory
{
public IPerson GetPerson(PersonType type)
{
getswitch (type)
{
returncase 11PersonType.5m;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.
public class PizzaFactory
 
<syntaxhighlight lang="csharp">
public interface IProduct
{
string GetName();
public enum PizzaType
bool SetPrice(double price);
}
 
public class Phone : IProduct
{
private double _price;
 
public string GetName()
{
HamMushroom,return "Apple TouchPad";
Deluxe,
Hawaiian
}
 
public staticbool IPizza CreatePizzaSetPrice(PizzaTypedouble pizzaTypeprice)
{
IPizza ret_price = nullprice;
return true;
}
}
 
/* Almost same as Factory, just an additional exposure to do something with the created method */
switch (pizzaType)
public abstract class ProductAbstractFactory
{
{
case PizzaType.HamMushroom:
protected abstract IProduct MakeProduct();
ret = new HamAndMushroomPizza();
 
public IProduct GetObject() // Implementation of Factory Method.
break;
{
case PizzaType.Deluxe:
return ret = new DeluxePizzathis.MakeProduct();
 
break;
case PizzaType.Hawaiian:
ret = new HawaiianPizza();
 
break;
default:
throw new ArgumentException("The pizza type " + pizzaType + " is not recognized.");
}
 
return ret;
}
}
 
public class PizzaLoverPhoneConcreteFactory : ProductAbstractFactory
{
protected override IProduct MakeProduct()
public static void Main(string[] args)
{
IProduct product = new Phone();
Dictionary<PizzaFactory.PizzaType, IPizza> pizzas = new Dictionary<PizzaFactory.PizzaType, IPizza>();
// Do something with the object after receiving it
product.SetPrice(20.30);
foreach (PizzaFactory.PizzaType pizzaType in Enum.GetValues(typeof(PizzaFactory.PizzaType)))
{return product;
pizzas.Add(pizzaType, PizzaFactory.CreatePizza(pizzaType));
}
foreach (PizzaFactory.PizzaType pizzaType in pizzas.Keys)
{
System.Console.WriteLine("Price of {0} is {1}", pizzaType, pizzas[pizzaType].Price);
}
}
}
</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]]====
Output:
This [[Java (programming language)|Java]] example is similar to one in the book ''[[Design Patterns]].''
Price of HamMushroom is 8.5
Price of Deluxe is 10.5
Price of Hawaiian is 11.5
</source>
 
[[File:Maze game UML.svg]]
=== [[Common Lisp]] ===
Factory methods are not really needed, because classes and class names are first class values.
 
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:
<source lang="Lisp">
(defclass pizza ()
((price :accessor price)))
 
<syntaxhighlight lang="java">
(defclass ham-and-mushroom-pizza (pizza)
public abstract class Room {
((price :initform 850)))
abstract void connect(Room room);
 
(defclass deluxe-pizza (pizza)
((price :initform 1050)))
 
(defclass hawaiian-pizza (pizza)
((price :initform 1150)))
 
(defparameter *pizza-types*
(list 'ham-and-mushroom-pizza
'deluxe-pizza
'hawaiian-pizza))
 
(loop for pizza-type in *pizza-types*
do (format t "~%Price of ~a is ~a"
pizza-type
(price (make-instance pizza-type))))
 
Output:
Price of HAM-AND-MUSHROOM-PIZZA is 850
Price of DELUXE-PIZZA is 1050
Price of HAWAIIAN-PIZZA is 1150
</source>
 
=== Java ===
<source lang="java">
abstract class Pizza {
public abstract int getPrice(); // count the cents
}
 
public class HamAndMushroomPizzaMagicRoom extends PizzaRoom {
public intvoid getPriceconnect(Room room) {}
return 850;
}
}
 
public class DeluxePizzaOrdinaryRoom extends PizzaRoom {
public intvoid getPriceconnect(Room room) {}
return 1050;
}
}
 
public abstract class MazeGame {
class HawaiianPizza extends Pizza {
private final List<Room> rooms = new ArrayList<>();
public int getPrice() {
 
return 1150;
public MazeGame() {
}
Room room1 = makeRoom();
Room room2 = makeRoom();
room1.connect(room2);
rooms.add(room1);
rooms.add(room2);
}
 
abstract protected Room makeRoom();
}
</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:
class PizzaFactory {
public enum PizzaType {
HamMushroom,
Deluxe,
Hawaiian
}
 
<syntaxhighlight lang="java">
public static Pizza createPizza(PizzaType pizzaType) {
public class MagicMazeGame extends MazeGame {
switch (pizzaType) {
@Override
case HamMushroom:
protected MagicRoom makeRoom() {
return new HamAndMushroomPizza();
return new case Deluxe:MagicRoom();
return new DeluxePizza();
case Hawaiian:
return new HawaiianPizza();
}
throw new IllegalArgumentException("The pizza type " + pizzaType + " is not recognized.");
}
}
 
public class OrdinaryMazeGame extends MazeGame {
class PizzaLover {
/*@Override
protected OrdinaryRoom makeRoom() {
* Create all available pizzas and print their prices
return new OrdinaryRoom();
*/
public static void main (String args[]) {
for (PizzaFactory.PizzaType pizzaType : PizzaFactory.PizzaType.values()) {
System.out.println("Price of " + pizzaType + " is " + PizzaFactory.createPizza(pizzaType).getPrice());
}
}
}
 
MazeGame ordinaryGame = new OrdinaryMazeGame();
Output:
MazeGame magicGame = new MagicMazeGame();
Price of HamMushroom is 850
</syntaxhighlight>
Price of Deluxe is 1050
Price of Hawaiian is 1150
</source>
 
=== Javascript =[[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">
This example uses [[Firebug (web development)|Firebug]] console to output information.
/* Factory and car interfaces */
 
interface CarFactory
<source lang="javascript">
{
/**
public function makeCar(): Car;
* Extends parent class with child. In Javascript, the keyword "extends" is not
* currently implemented, so it must be emulated.
* Also it is not recommended to use keywords for future use, so we name this
* function "extends" with capital E. Javascript is case-sensitive.
*
* @param function parent constructor function
* @param function (optional) used to override default child constructor function
*/
function Extends(parent, childConstructor) {
 
var F = function () {};
 
F.prototype = parent.prototype;
 
var Child = childConstructor || function () {};
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.parent = parent.prototype;
 
// return instance of new object
return Child;
}
 
interface Car
 
{
/**
public function getType(): string;
* Abstract Pizza object constructor
*/
function Pizza() {
throw new Error('Cannot instantiate abstract object!');
}
Pizza.prototype.price = 0;
Pizza.prototype.getPrice = function () {
return this.price;
}
 
/* Concrete implementations of the factory and car */
var HamAndMushroomPizza = Extends(Pizza);
HamAndMushroomPizza.prototype.price = 8.5;
 
class SedanFactory implements CarFactory
var DeluxePizza = Extends(Pizza);
DeluxePizza.prototype.price = 10.5;
 
var HawaiianPizza = Extends(Pizza);
HawaiianPizza.prototype.price = 11.5;
 
 
var PizzaFactory = {
createPizza: function (type) {
var baseObject = 'Pizza';
var targetObject = type.charAt(0).toUpperCase() + type.substr(1);
 
if (typeof window[targetObject + baseObject] === 'function') {
return new window[targetObject + baseObject];
}
else {
throw new Error('The pizza type ' + type + ' is not recognized.');
}
}
};
 
//var price = PizzaFactory.createPizza('deluxe').getPrice();
var pizzas = ['HamAndMushroom', 'Deluxe', 'Hawaiian'];
for (var i in pizzas) {
console.log('Price of ' + pizzas[i] + ' is ' + PizzaFactory.createPizza(pizzas[i]).getPrice());
}
</source>
'''Output'''<br/>
<pre>
Price of HamAndMushroom is 8.50
Price of Deluxe is 10.50
Price of Hawaiian is 11.50
</pre>
 
=== Python ===
<source lang="python">
#
# Pizza
#
class Pizza:
def __init__(self):
self.price = None
def get_price(self):
return self.price
class HamAndMushroomPizza(Pizza):
def __init__(self):
self.price = 8.5
class DeluxePizza(Pizza):
def __init__(self):
self.price = 10.5
class HawaiianPizza(Pizza):
def __init__(self):
self.price = 11.5
 
#
# PizzaFactory
#
class PizzaFactory:
@staticmethod
def create_pizza(pizza_type):
if pizza_type == 'HamMushroom':
return HamAndMushroomPizza()
elif pizza_type == 'Deluxe':
return DeluxePizza()
elif pizza_type == 'Hawaiian':
return HawaiianPizza()
if __name__ == '__main__':
for pizza_type in ('HamMushroom', 'Deluxe', 'Hawaiian'):
print 'Price of {0} is {1}'.format(pizza_type, PizzaFactory.create_pizza(pizza_type).get_price())
 
</source>
 
=== PHP ===
<source lang="PHP">
<?php
 
abstract class Pizza
{
public function makeCar(): Car
protected $_price;
public function getPrice()
{
return $this->_pricenew Sedan();
}
}
 
class Sedan implements Car
class HamAndMushroomPizza extends Pizza
{
public function getType(): string
protected $_price = 8.5;
}
class DeluxePizza extends Pizza
{
protected $_price = 10.5;
}
class HawaiianPizza extends Pizza
{
protected $_price = 11.5;
}
class PizzaFactory
{
public static function createPizza($type)
{
$baseClass =return 'PizzaSedan';
$targetClass = ucfirst($type).$baseClass;
if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass))
return new $targetClass;
else
throw new Exception("The pizza type '$type' is not recognized.");
}
}
 
/* Client */
$pizzas = array('HamAndMushroom','Deluxe','Hawaiian');
foreach($pizzas as $p) {
printf(
"Price of %s is %01.2f".PHP_EOL ,
$p ,
PizzaFactory::createPizza($p)->getPrice()
);
}
 
$factory = new SedanFactory();
$car = $factory->makeCar();
print $car->getType();
</syntaxhighlight>
 
==== [[Python (programming language)|Python]] ====
// Output:
This Python example employs the same as did the previous Java example.
// Price of HamAndMushroom is 8.50
// Price of Deluxe is 10.50
// Price of Hawaiian is 11.50
 
<syntaxhighlight lang="python3">
?>
from abc import ABC, abstractmethod
</source>
 
=== Delphi ===
<source lang="delphi">
program FactoryMethod;
 
class MazeGame(ABC):
{$APPTYPE CONSOLE}
def __init__(self) -> None:
self.rooms = []
self._prepare_rooms()
 
def _prepare_rooms(self) -> None:
uses
room1 = self.make_room()
SysUtils;
room2 = self.make_room()
 
room1.connect(room2)
type
self.rooms.append(room1)
self.rooms.append(room2)
 
def play(self) -> None:
// Product
print(f"Playing using {self.rooms[0]}")
TProduct = class(TObject)
public
function GetName(): string; virtual; abstract;
end;
 
@abstractmethod
// ConcreteProductA
def make_room(self):
TConcreteProductA = class(TProduct)
raise NotImplementedError("You should implement this!")
public
function GetName(): string; override;
end;
 
// ConcreteProductB
TConcreteProductB = class(TProduct)
public
function GetName(): string; override;
end;
 
class MagicMazeGame(MazeGame):
// Creator
def make_room(self) -> "MagicRoom":
TCreator = class(TObject)
return MagicRoom()
public
function FactoryMethod(): TProduct; virtual; abstract;
end;
 
// ConcreteCreatorA
TConcreteCreatorA = class(TCreator)
public
function FactoryMethod(): TProduct; override;
end;
 
class OrdinaryMazeGame(MazeGame):
// ConcreteCreatorB
def make_room(self) -> "OrdinaryRoom":
TConcreteCreatorB = class(TCreator)
return OrdinaryRoom()
public
function FactoryMethod(): TProduct; override;
end;
 
{ ConcreteProductA }
function TConcreteProductA.GetName(): string;
begin
Result := 'ConcreteProductA';
end;
 
class Room(ABC):
{ ConcreteProductB }
def __init__(self) -> None:
function TConcreteProductB.GetName(): string;
self.connected_rooms = []
begin
Result := 'ConcreteProductB';
end;
 
def connect(self, room: "Room") -> None:
{ ConcreteCreatorA }
self.connected_rooms.append(room)
function TConcreteCreatorA.FactoryMethod(): TProduct;
begin
Result := TConcreteProductA.Create();
end;
 
{ ConcreteCreatorB }
function TConcreteCreatorB.FactoryMethod(): TProduct;
begin
Result := TConcreteProductB.Create();
end;
 
class MagicRoom(Room):
const
def __str__(self) -> str:
Count = 2;
return "Magic room"
 
var
Creators: array[1..Count] of TCreator;
Product: TProduct;
I: Integer;
 
class OrdinaryRoom(Room):
begin
def __str__(self) -> str:
// An array of creators
return "Ordinary room"
Creators[1] := TConcreteCreatorA.Create();
Creators[2] := TConcreteCreatorB.Create();
 
// Iterate over creators and create products
for I := 1 to Count do
begin
Product := Creators[I].FactoryMethod();
WriteLn(Product.GetName());
Product.Free();
end;
 
ordinaryGame = OrdinaryMazeGame()
for I := 1 to Count do
ordinaryGame.play()
Creators[I].Free();
 
magicGame = MagicMazeGame()
ReadLn;
magicGame.play()
end.
</syntaxhighlight>
</source>
 
==Uses==
* In [[ADO.NET]], [httphttps://msdn2docs.microsoft.com/en-us/librarydotnet/api/system.data.idbcommand.createparameter?view=netframework-4.aspx8 IDbCommand.CreateParameter] is an example of the use of factory method to connect parallel class hierarchies.
* In [[Qt (toolkit)|Qt]], [http://docqt-project.trolltech.comorg/doc/4qt-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 whichthat can be overridden in [[application code]].
* In [[Java (programming language)|Java]], several factories are used in the [http://javadownload.sunoracle.com/j2sejavase/1.45.20/docs/api/javax/xml/parsers/package-summary.html javax.xml.parsers] package., e.g.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
* [[Design pattern]], overview of design patterns in general
* [[Abstract factory pattern]], a pattern often implemented using 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]]''.
*[[Factory object]]
 
==Notes==
{{Reflist}}
==References==
<references/>
*{{cite 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
| last = Fowler | first = Martin
| title = Refactoring: Improving the Design of Existing Code
| coauthors = [[Kent Beck]], [[John Brant (author)|John Brant]], [[William Opdyke]], and [[Don Roberts (author)|Don Roberts]]
| title = [[Refactoring]]: Improving the Design of Existing Code
| publisher = Addison-Wesley
| month date= June | year = 1999
| isbn = 0-201-48567-2
| author1-link=Martin Fowler (software engineer) }}
}}
*{{cite book |author1=Cox, Brad J. |
title=Object-oriented programming: an evolutionary approach |
author=[[Erich Gamma|Gamma, Erich]]; [[Richard Helm|Helm, Richard]]; Johnson, Ralph; Vlissides, John |
title=[[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]] |
publisher=Addison-Wesley |
year=19941986 |
isbn=978-0-201-6336110393-29
}}|
title-link=Object-oriented programming }}
*{{cite journal |
last=Cohen |
first=Tal |author2=Gil, Joseph |
coauthors=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 |
formataccess-date=[[PDF]] |2007-03-12
accessdate=2007-03-12|
doi=10.5381/jot.2007.6.6.a3 |
}}
doi-access=free }}
 
==External links==
{{Wikibooks
*[http://sourcemaking.com/design_patterns/factory_method Factory Method Design Pattern] in Source Making
| 1 = Computer Science Design Patterns
*[http://www.patterns.24bytes.com/2009/04/factory-method-design-pattern.html Factory method Example UML and Code]
| 2 = Factory method examples
*[http://www.lepus.org.uk/ref/companion/FactoryMethod.xml Factory method in UML and in LePUS3] (a Design Description Language)
}}
*[http://c2.com/cgi/wiki?FactoryMethodPattern Description from the Portland Pattern Repository]
* [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
*[http://www.fsw.com/Jt/Jt.htm Jt] J2EE Pattern Oriented Framework
 
* [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)
* [http://drdobbs.com/java/208403883 Consider static factory methods] by Joshua Bloch
 
{{Design Patterns Patterns}}
 
{{DEFAULTSORT:Factory Method Pattern}}
<!--Categories-->
[[Category:Software design patterns]]
[[Category:Articles with example Java code]]
[[Category:ArticlesMethod with(computer example Python codeprogramming)]]
[[Category:MethodArticles (computerwith science)example C Sharp code]]
[[Category:Articles with example PHP code]]
 
[[bg:Метод Фабрика (шаблон)]]
[[ca:Factory method]]
[[de:Fabrikmethode]]
[[es:Factory Method (patrón de diseño)]]
[[fr:Fabrique (patron de conception)]]
[[ko:팩토리 메서드 패턴]]
[[it:Factory method]]
[[he:תבנית Factory Method]]
[[ml:ഫാക്ടറി മെത്തേഡ് പാറ്റേൺ]]
[[nl:Factory (ontwerppatroon)]]
[[ja:Factory Method パターン]]
[[pl:Metoda wytwórcza (wzorzec projektowy)]]
[[pt:Factory Method]]
[[ru:Фабричный метод (шаблон проектирования)]]
[[sr:Фабрички метод (пројектни узорак)]]
[[th:แฟกทอรีเมธอดแพตเทิร์น]]
[[uk:Фабричний метод (шаблон проектування)]]
[[vi:Factory method pattern]]
[[zh:工厂方法]]