Factory method pattern: Difference between revisions

Content deleted Content added
No edit summary
Tags: Reverted possible vandalism references removed Disambiguation links added
Undid revision 1161688732 by 173.61.86.226 (talk)
Tags: Undo Mobile edit Mobile web edit Advanced mobile edit
Line 1:
{{Short description|Object-oriented software design pattern}}
[[Image:FactoryMethod.svg|thumb|right|300px|Factory method in [[Unified Modeling Language|UML]]]]
In [[class-based programming]], the '''factory method pattern''' is a [[creational pattern]] that uses factory methods to deal with the problem of [[object creation|creating objects]] without having to specify the exact [[class (computer programming)|class]] of the object that will be created. This is done by creating objects by calling a factory method—either specified in an [[Interface (object-oriented programming)|interface]] and implemented by child classes, or implemented in a base class and optionally [[method overriding|overridden]] by derived classes—rather than by calling a [[Constructor (object-oriented programming)|constructor]].
[[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
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.
<ref name="GoF">{{cite book|author1=Erich Gamma |author2= Richard Helm |author3= Ralph Johnson|author4= John Vlissides|title=Design Patterns: Elements of Reusable Object-Oriented Software|year=1994|publisher=Addison Wesley|isbn=0-201-63361-2|pages=121ff}}</ref>
design pattern is one of the twenty-three well-known ''[[Design Patterns|design patterns]]'' that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.
 
The Factory Method design pattern solves problems like:
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.
<ref>{{cite web|title=The Factory Method design pattern - Problem, Solution, and Applicability|url=http://w3sdesign.com/?gr=c03&ugr=proble|website=w3sDesign.com|accessdate=2017-08-17}}</ref>
* How can an object be created so that subclasses can redefine which class to instantiate?
* How can a class defer instantiation to subclasses?
 
The Factory Method design pattern describes how to solve such problems:
==Definition==
* Define a separate operation (''factory method'') for creating an object.
The essence of the Factory method Pattern is to "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>Gang Of Four</ref>
* Create an object by calling a ''factory method''.
 
This enables writing of subclasses to change the way an object is created (to redefine which class to instantiate).<br>
==Common usage==
See also the UML class diagram below.
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.
 
==Definition==
Parallel class hierarchies often require objects from one hierarchy to be able to create appropriate objects from another.
"Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses." ([[Gang of Four (software)|Gang Of Four]])
 
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 not accessible to the composing object, may not provide a sufficient level of abstraction, or may otherwise not be part of 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 [[subclass (computer science)|subclasses]] can then override to specify the [[Subtyping|derived type]] of product that will be created.
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.
 
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
==Other benefits and variants==
| last1 = Freeman
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.
| first1 = Eric
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.
| last2 = Freeman
 
| first2 = Elisabeth
===Descriptive names===
| last3 = Kathy
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]]):
| first3 = Sierra
<source lang="java">
| last4 = Bert
class Complex
| first4 = Bates
{
| editor-last1 = Hendrickson
public static Complex fromCartesian(double real, double imag) {
| editor-first1 = Mike
return new Complex(real, imag);
| editor-last2 = Loukides
}
| editor-first2 = Mike
| year = 2004
public static Complex fromPolar(double modulus, double angle) {
| title = Head First Design Patterns
return new Complex(modulus * cos(angle), modulus * sin(angle));
| volume } = 1
| page = 162
| publisher = O'REILLY
private Complex(double a, double b) {
| format //...= paperback
| isbn = 978-0-596-00712-6
}
| access-date = 2012-09-12
}
| url = http://shop.oreilly.com/product/9780596007126.do
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.
 
===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.
 
Consider as an example a program to read [[image file]]s and make [[thumbnail]]s out of them.
The program supports different image formats, represented by a reader class for each format:
<source lang="java">
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);
 
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>
As shown in the C# example below, the factory method pattern can also rely on an Interface - in this case IPerson - to be implemented.
 
==ExampleStructure==
 
=== ABAPUML class diagram ===
<source lang="abap">
REPORT zz_pizza_factory_test NO STANDARD PAGE HEADING .
 
[[File:w3sDesign Factory Method Design Pattern UML.jpg|frame|none|A sample UML class diagram for the Factory Method design pattern.
TYPES ty_pizza_type TYPE i .
<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>]]
 
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.
* CLASS lcl_pizza DEFINITION
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 which concrete class is instantiated.
CLASS lcl_pizza DEFINITION ABSTRACT .
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.
 
== Examples ==
PUBLIC SECTION .
This C++14 implementation is based on the pre C++98 implementation in the book.<ref>{{cite book |author=Erich Gamma |title=Design Patterns: Elements of Reusable Object-Oriented Software |publisher=Addison Wesley |year=1994 |isbn=0-201-63361-2 |pages=123 ff.}}</ref>
<syntaxhighlight lang="c++">
#include <iostream>
#include <memory>
 
enum ProductId {MINE, YOURS};
DATA p_pizza_name TYPE string .
 
// defines the interface of objects the factory method creates.
METHODS get_price ABSTRACT
class Product {
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>
 
class Document {
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::cout << "this=" << this << " print MINE\n";
{
}
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::cout << "this=" << this << " print YOURS\n";
{
}
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. Thus factory methods decouple callers (<code>MazeGame</code>) from the implementation of the concrete classes. This makes the "new" 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>
In the above code you can see the creation of one interface called <code>IPerson</code> and two implementations called <code>Villager</code> and <code>CityPerson</code>. Based on the type passed into the <code>PersonFactory</code> object, we are returning the original concrete object as the interface <code>IPerson</code>.
 
A factory method is just an addition to <code>PersonFactory</code> class. It creates the object of the class through interfaces but on the other hand, it also lets the subclass decide which class is instantiated.
 
<syntaxhighlight lang="csharp">
public interface IProduct
{
string GetName();
bool SetPrice(double price);
}
 
public class PizzaFactoryPhone : IProduct
{
publicprivate enumdouble PizzaType_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 you get the object.
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>
You can see we have used <code>MakeProduct</code> in concreteFactory. As a result, you can easily call <code>MakeProduct()</code> from it to get the <code>IProduct</code>. You might also write your custom logic after getting the object in the concrete Factory Method. The GetObject 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 MazeGame uses Rooms but it puts the responsibility of creating Rooms to its subclasses which 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>
 
In the above snippet, the <code>MazeGame</code> constructor is a [[Template method pattern|template method]] that makes 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, it suffices to override the <code>makeRoom</code> method:
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]]====
Another example in [[PHP]] follows, this time using interface implementations as opposed to subclassing (however, the same can be achieved through subclassing). It is important to note that the factory method can also be defined as public and called directly by the client code (in contrast with the Java example above).
 
<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:
Same as 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] 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. 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]]'', which he says has no direct equivalent in ''[[Design Patterns]]''.
*[[Factory object]]
 
==References==
{{Reflist}}
<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=Gamma, Erich |author2-link=Richard Helm |author2=Helm, Richard |author3=Johnson, Ralph |author4=Vlissides, John |
*{{cite book |
title=Design Patterns: Elements of Reusable Object-Oriented Software |
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=1994 |
isbn=0-201-63361-2
|author1-link=Erich Gamma |title-link=Design Patterns }}
}}
*{{cite book |author1=Cox, Brad J. |
title=Object-oriented programming: an evolutionary approach |
publisher=Addison-Wesley |
year=1986 |
isbn=978-0-201-10393-9
|
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://wwwdesignpattern.fswco.comil/Jt/JtFactory.htmhtml Jt]Factory J2EEDesign Pattern] Implementation Orientedin FrameworkJava
 
* [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:工厂方法]]