Factory method pattern: Difference between revisions

Content deleted Content added
Tag: Reverted
Examples: fixed weasel word
 
(34 intermediate revisions by 23 users not shown)
Line 1:
{{Short description|Object-oriented software design pattern}}
In [[classobject-basedoriented 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 Thisprogramming)|constructor]], this 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 derivedsubclasses. classes—ratherIt thanis byone callingof athe 23 classic design patterns described in the book ''[[ConstructorDesign Patterns]]'' (object-orientedoften programmingreferred to as the "Gang of Four" or simply "GoF")|constructor and is subcategorized as a [[creational pattern]].{{sfn|Gamma|Helm|Johnson|Vlissides|1995|page=107}}
 
==Overview==
The factory method design pattern solves problems such as:
The Factory Method
* 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.
<ref name="GoF">{{cite book|author=Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides|title=Design Patterns: Elements of Reusable Object-Oriented Software|year=1994|publisher=Addison Wesley|isbn=0-201-63361-2|pages=107ff}}</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 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.
 
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).
The Factory Method design pattern solves problems like:
<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:
* Define a separate operation (''factory method'') for creating an object.
* 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>
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 [[subclass (computer science)|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 56 ⟶ 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.
== Examples ==
Instead, the <code>Creator</code> refers to a separate <code>factoryMethod()</code> to create a product object,
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}}
which makes the <code>Creator</code> independent of which concrete class is instantiated.
<syntaxhighlight lang="c++">
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.
import std;
 
enum class ProductId {MINE, YOURS};
 
// defines the interface of objects the factory method creates.
class Product {
public:
virtual void print() = 0;
virtual ~Product() = default;
};
 
// implements the Product interface.
class ConcreteProductMINE: public Product {
public:
void print() {
std::println("this={} print MINE", this);
}
};
 
// implements the Product interface.
class ConcreteProductYOURS: public Product {
public:
void print() {
std::println("this={} print YOURS", this);
}
};
 
// declares the factory method, which returns an object of type Product.
class Creator {
public:
virtual std::unique_ptr<Product> create(ProductId id) {
if (ProductId::MINE == id) return std::make_unique<ConcreteProductMINE>();
if (ProductId::YOURS == id) return std::make_unique<ConcreteProductYOURS>();
// repeat for remaining products...
 
return nullptr;
}
virtual ~Creator() = default;
};
 
int main() {
// The unique_ptr prevent memory leaks.
std::unique_ptr<Creator> creator = std::make_unique<Creator>();
std::unique_ptr<Product> product = creator->create(ProductId::MINE);
product->print();
 
product = creator->create(ProductId::YOURS);
product->print();
}
</syntaxhighlight>
 
The program output is like
 
<syntaxhighlight lang="c++">
this=0x6e5e90 print MINE
this=0x6e62c0 print YOURS
</syntaxhighlight>
 
== Example ==
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.
 
Line 68 ⟶ 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 105 ⟶ 129:
/// Implementation of Factory - Used to create objects.
/// </summary>
public class FactoryPersonFactory
{
public IPerson GetPerson(PersonType type)
Line 121 ⟶ 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>FactoryPersonFactory</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>FactoryPersonFactory</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 164 ⟶ 188:
{
IProduct product = new Phone();
// Do something with the object after youreceiving get the object.it
product.SetPrice(20.30);
return product;
Line 170 ⟶ 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]]====
This [[Java (programming language)|Java]] example is similar to one in the book ''[[Design Patterns]].''
Also see: [https://thegeekyasian.com/strategy-and-factory-design-patterns-the-right-way/ Factory Pattern in Spring Boot:: The Right Way]
 
[[File:Maze game UML.svg]]
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:
 
The <code>MazeGame</code> uses <code>Room</code> but delegates the responsibility of creating <code>Room</code> objects to its subclasses that create the concrete classes. The regular game mode could use this template method:
 
<syntaxhighlight lang="java">
Line 206 ⟶ 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 228 ⟶ 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 269 ⟶ 294:
 
==== [[Python (programming language)|Python]] ====
SameThis Python example employs the same as did the previous Java example.
 
<syntaxhighlight lang="python3">
Line 333 ⟶ 358:
==Uses==
* In [[ADO.NET]], [https://docs.microsoft.com/en-us/dotnet/api/system.data.idbcommand.createparameter?view=netframework-4.8 IDbCommand.CreateParameter] is an example of the use of factory method to connect parallel class hierarchies.
* In [[Qt (toolkit)|Qt]], [http://qt-project.org/doc/qt-5.0/qtwidgets/qmainwindow.html#createPopupMenu QMainWindow::createPopupMenu] {{Webarchive|url=https://web.archive.org/web/20150719014739/http://qt-project.org/doc/qt-5.0/qtwidgets/qmainwindow.html#createPopupMenu |date=2015-07-19 }} is a factory method declared in a framework that can be overridden in [[application code]].
* In [[Java (programming language)|Java]], several factories are used in the [http://download.oracle.com/javase/1.5.0/docs/api/javax/xml/parsers/package-summary.html javax.xml.parsers] package., 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 343 ⟶ 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]]''.
 
==Notes==
{{Reflist}}
==References==
{{Reflist}}
*{{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 354 ⟶ 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 |
Line 388 ⟶ 408:
| 2 = Factory method examples
}}
* [http://designpattern.co.il/Factory.html Factory Design Pattern] {{Webarchive|url=https://web.archive.org/web/20180110103637/http://designpattern.co.il/Factory.html |date=2018-01-10 }} Implementation in Java
 
* [https://web.archive.org/web/20080503082912/http://www.lepus.org.uk/ref/companion/FactoryMethod.xml Factory method in UML and in LePUS3] (a Design Description Language)