Factory method pattern: Difference between revisions

Content deleted Content added
Rescuing 2 sources and tagging 0 as dead.) #IABot (v2.0.9.5
Examples: fixed weasel word
 
(15 intermediate revisions by 11 users not shown)
Line 1:
{{Short description|Object-oriented software design pattern}}
In [[object -oriented programming]], the '''factory method pattern''' is a [[creationalsoftware design pattern|design pattern]] that uses factory methods to deal with the problem of [[object creation|creating objects]] without having to specify thetheir exact [[class (computer programming)|classclasses]]. ofRather thethan objectby thatcalling willa be[[Constructor created.(object-oriented programming)|constructor]], Thisthis is doneaccomplished by creatinginvoking objectsa byfactory callingmethod ato factorycreate method—eitheran object. Factory methods can be specified in an [[Interface (object-oriented programming)|interface]] and implemented by child classes,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 ''[[derivedDesign class|derived classesPatterns]]—rather'' than(often byreferred callingto as the "Gang of Four" or simply "GoF") and is subcategorized as a [[Constructorcreational (object-oriented programming)|constructorpattern]].{{sfn|Gamma|Helm|Johnson|Vlissides|1995|page=107}}
 
==Overview==
The Factoryfactory Methodmethod design pattern solves problems likesuch as:
The Factory Method
* DefineHow acan 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''.
<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>
* 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.
design pattern is one of 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.
 
This enables the writingcreation of subclasses that can change the way in which an object is created (e.g.for example, by redefining which class to instantiate).<br>
The Factory Method design pattern solves problems like:
* How can an object be created so that [[Subclass (computer science)|subclasses]] can redefine its subsequent and distinct implementation?
* How can an object's instantiation be deferred to a subclass?
 
The Factory Method design pattern describes how to solve such problems:
* Define a ''factory method'' within the [[Superclass (computer science)|superclass]] that defers the object's creation to a subclass's ''factory method''.
* Create an object by calling a ''factory method'' instead of directly calling a constructor.
 
This enables the writing of subclasses that can change the way an object is created (e.g. by redefining which class to instantiate).<br>
See also the UML class diagram below.
 
==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. The Factory method lets a class defer instantiation it uses to subclasses."<ref ([[Gangname="gof">{{cite book |last1=Gamma |first1=Erich |author1-link=Erich Gamma |title=Design Patterns: Elements of FourReusable Object-Oriented Software |title-link=Design Patterns |last2=Helm |first2=Richard |author2-link=Richard Helm |last3=Johnson |first3=Ralph |author3-link=Ralph Johnson (softwarecomputer scientist) |Ganglast4=Vlissides Of|first4=John Four]])|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 not accessibleinaccessible to the composing object, may not provide a sufficient level of abstraction, or may otherwise not be partincluded ofin 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]].
| last1 = Freeman
| first1 = Eric
| last2 = Freeman
| first2 = Elisabeth
| last3 = Kathy
| first3 = Sierra
| last4 = Bert
| first4 = Bates
| editor-last1 = Hendrickson
| editor-first1 = Mike
| editor-last2 = Loukides
| editor-first2 = Mike
| year = 2004
| title = Head First Design Patterns
| volume = 1
| page = 162
| publisher = O'REILLY
| format = paperback
| isbn = 978-0-596-00712-6
| access-date = 2012-09-12
| url = http://shop.oreilly.com/product/9780596007126.do
}}</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.
 
==Structure==
Line 55 ⟶ 24:
<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. 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.
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 which concrete class 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.
 
== Examples ==
This [[C++1423]] implementation is based on the pre C++98 implementation in the ''[[Design Patterns]]'' book.<ref>{{cite book sfn|author=Erich Gamma |title=Design Patterns: Elements of Reusable Object-Oriented Software Helm|publisher=Addison Wesley Johnson|year=1994 Vlissides|isbn=0-201-63361-2 1995|pagespage=123 ff.122}}</ref>
<syntaxhighlight lang="c++">
import std;
#include <iostream>
#include <memory>
 
enum class ProductId {MINE, YOURS};
 
// defines the interface of objects the factory method creates.
Line 80 ⟶ 44:
public:
void print() {
std::cout << println("this=" << this << "{} print MINE\n", this);
}
};
Line 88 ⟶ 52:
public:
void print() {
std::cout << println("this=" << this << "{} print YOURS\n", this);
}
};
Line 128 ⟶ 92:
[[File:New WikiFactoryMethod.png|734x734px|center]]
 
<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 factoryFactory methods thus decouple callers (<code>MazeGame</code>) from the implementation of the concrete classes. This makes the "<code>new"</code> Operatoroperator redundant, allows adherence to the [[Open/closedopen–closed principle]] and makes the final product more flexible in the event of change.
 
=== Example implementations ===
Line 181 ⟶ 145:
}
</syntaxhighlight>
In theThe above code you can seedepicts the creation of onean interface called <code>IPerson</code> and two implementations called <code>Villager</code> and <code>CityPerson</code>. Based on the type passed intoto the <code>PersonFactory</code> object, we are returning 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 on the other hand, it also letsallows the subclass to decide which class is instantiated.
 
<syntaxhighlight lang="csharp">
Line 224 ⟶ 188:
{
IProduct product = new Phone();
// Do something with the object after youreceiving get the object.it
product.SetPrice(20.30);
return product;
Line 230 ⟶ 194:
}
</syntaxhighlight>
YouIn canthis see we have usedexample, <code>MakeProduct</code> is used in <code>concreteFactory</code>. As a result, you can easily call <code>MakeProduct()</code> frommay itbe invoked in order to getretrieve it from the <code>IProduct</code>. YouCustom might alsologic writecould your custom logicrun after getting the object is obtained in the concrete Factoryfactory Methodmethod. The <code>GetObject</code> is made abstract in the Factoryfactory interface.
 
====[[Java (programming language)|Java]]====
Line 237 ⟶ 201:
[[File:Maze game UML.svg]]
 
The <code>MazeGame</code> uses Rooms<code>Room</code> but it putsdelegates the responsibility of creating Rooms<code>Room</code> objects to its subclasses whichthat create the concrete classes. The regular game mode could use this template method:
 
<syntaxhighlight lang="java">
Line 267 ⟶ 231:
</syntaxhighlight>
 
In the above snippet, theThe <code>MazeGame</code> constructor is a [[Template method pattern|template method]] that makesadds 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 may be overridden:
 
<syntaxhighlight lang="java">
Line 289 ⟶ 253:
 
====[[PHP]]====
Another example inThis [[PHP]] follows, this timeexample usingshows interface implementations asinstead opposed toof subclassing (however, the same can be achieved through subclassing). It is important to note that theThe factory method can also be defined as <code>public </code>and called directly by the client code (in contrast withto the previous Java example above).
 
<syntaxhighlight lang="php">
Line 330 ⟶ 294:
 
==== [[Python (programming language)|Python]] ====
SameThis Python example employs the same as did the previous Java example.
 
<syntaxhighlight lang="python3">
Line 395 ⟶ 359:
* 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., 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==
Line 404 ⟶ 368:
* [[Builder pattern]], another creational pattern
* [[Template method pattern]], which may call factory methods
* [[Joshua Bloch]]'s idea of a ''[[static factory method]]'', for which heBloch claims saysthere hasis no direct equivalent in ''[[Design Patterns]]''.
 
==ReferencesNotes==
{{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
Line 415 ⟶ 380:
| 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 |
title=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 |