Content deleted Content added
→Examples: fixed weasel word |
|||
(42 intermediate revisions by 26 users not shown) | |||
Line 1:
{{Short description|Object-oriented software design pattern}}
In [[
==Overview==
The factory method design pattern solves problems such as:
* How can an object's [[Subclass (computer science)|subclasses]] redefine its subsequent and distinct implementation? The pattern involves creation of a factory method within the [[Superclass (computer science)|superclass]] that defers the object's creation to a subclass's factory method.
* How can an object's instantiation be deferred to a subclass? Create an object by calling a factory method instead of directly calling a constructor.
This enables the creation of subclasses that can change the way in which an object is created (for example, by redefining which class to instantiate).
==Definition==
According to ''[[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]]'': "Define an interface for creating an object, but let subclasses decide which class to instantiate.
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
The factory method pattern relies on inheritance, as object creation is delegated to subclasses that implement the factory method to create objects.<ref>{{cite book |last1=Freeman |first1=Eric |url=http://shop.oreilly.com/product/9780596007126.do |title=Head First Design Patterns: A Brain-Friendly Guide |last2=Robson |first2=Elisabeth |last3=Sierra |first3=Kathy |last4=Bates |first4=Bert |publisher=O'Reilly Media |year=2004 |isbn=978-0-596-00712-6 |editor-last1=Hendrickson |editor-first1=Mike |edition=1st |volume=1 |page=162 |format=paperback |access-date=2012-09-12 |editor-last2=Loukides |editor-first2=Mike}}</ref>
The pattern can also rely on the implementation of an [[Interface (object-oriented programming)|interface]].
==Structure==
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.
== Examples ==
This [[C++23]] implementation is based on the pre C++98 implementation in the ''[[Design Patterns]]'' book.{{sfn|Gamma|Helm|Johnson|Vlissides|1995|page=122}}
<syntaxhighlight lang="c++">
import std;
enum class 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>
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.
=== Example implementations ===
Line 105 ⟶ 129:
/// Implementation of Factory - Used to create objects.
/// </summary>
public class
{
public IPerson GetPerson(PersonType type)
Line 121 ⟶ 145:
}
</syntaxhighlight>
A factory method is just an addition to the <code>
<syntaxhighlight lang="csharp">
Line 164 ⟶ 188:
{
IProduct product = new Phone();
// Do something with the object after
product.SetPrice(20.30);
return product;
Line 170 ⟶ 194:
}
</syntaxhighlight>
====[[Java (programming language)|Java]]====
This [[Java (programming language)|Java]] example is similar to one in the book ''[[Design Patterns]].''
[[File:Maze game UML.svg]]
The <code>MazeGame</code> uses <code>Room</code> but delegates the responsibility of creating <code>Room</code> objects to its subclasses that create the concrete classes. The regular game mode could use this template method:
<syntaxhighlight lang="java">
Line 205 ⟶ 231:
</syntaxhighlight>
<syntaxhighlight lang="java">
Line 227 ⟶ 253:
====[[PHP]]====
<syntaxhighlight lang="php">
Line 268 ⟶ 294:
==== [[Python (programming language)|Python]] ====
<syntaxhighlight lang="python3">
Line 332 ⟶ 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
* 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 342 ⟶ 368:
* [[Builder pattern]], another creational pattern
* [[Template method pattern]], which may call factory methods
* [[Joshua Bloch]]'s idea of a
==Notes==
{{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 353 ⟶ 380:
| isbn = 0-201-48567-2
| author1-link=Martin Fowler (software engineer) }}
*{{cite book |author1=Cox, Brad J. |
title=Object-oriented programming: an evolutionary approach |
Line 387 ⟶ 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)
|