Factory method pattern

Last updated

In object oriented programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify their exact class. Rather than by calling a constructor, this is done by calling a factory method to create an object. Factory methods can either be specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes.

Contents

Overview

The Factory Method [1] design pattern is one of twenty-three well-known 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:

The Factory Method design pattern describes how to solve such problems:

This enables the writing of subclasses that can change the way an object is created (e.g. by redefining which class to instantiate).
See also the UML class diagram below.

Definition

"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)

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 concerns. The factory method design pattern handles these problems by defining a separate method for creating the objects, which subclasses can then override to specify the 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. [2] 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

UML class diagram

A sample UML class diagram for the Factory Method design pattern. W3sDesign Factory Method Design Pattern UML.jpg
A sample UML class diagram for the Factory Method design pattern.

In the above UML class diagram, the Creator class that requires a Product object does not instantiate the Product1 class directly. Instead, the Creator refers to a separate factoryMethod() to create a product object, which makes the Creator independent of which concrete class is instantiated. Subclasses of Creator can redefine which class to instantiate. In this example, the Creator1 subclass implements the abstract factoryMethod() by instantiating the Product1 class.

Examples

This C++14 implementation is based on the pre C++98 implementation in the book. [4]

#include<iostream>#include<memory>enumProductId{MINE,YOURS};// defines the interface of objects the factory method creates.classProduct{public:virtualvoidprint()=0;virtual~Product()=default;};// implements the Product interface.classConcreteProductMINE:publicProduct{public:voidprint(){std::cout<<"this="<<this<<" print MINE\n";}};// implements the Product interface.classConcreteProductYOURS:publicProduct{public:voidprint(){std::cout<<"this="<<this<<" print YOURS\n";}};// declares the factory method, which returns an object of type Product.classCreator{public:virtualstd::unique_ptr<Product>create(ProductIdid){if(ProductId::MINE==id)returnstd::make_unique<ConcreteProductMINE>();if(ProductId::YOURS==id)returnstd::make_unique<ConcreteProductYOURS>();// repeat for remaining products...returnnullptr;}virtual~Creator()=default;};intmain(){// 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();}

The program output is like

this=0x6e5e90printMINEthis=0x6e62c0printYOURS

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.

Structure

New WikiFactoryMethod.png

Room is the base class for a final product (MagicRoom or OrdinaryRoom). MazeGame declares the abstract factory method to produce such a base product. MagicRoom and OrdinaryRoom are subclasses of the base product implementing the final product. MagicMazeGame and OrdinaryMazeGame are subclasses of MazeGame implementing the factory method producing the final products. Thus factory methods decouple callers (MazeGame) 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.

Example implementations

C#

// Empty vocabulary of actual objectpublicinterfaceIPerson{stringGetName();}publicclassVillager:IPerson{publicstringGetName(){return"Village Person";}}publicclassCityPerson:IPerson{publicstringGetName(){return"City Person";}}publicenumPersonType{Rural,Urban}/// <summary>/// Implementation of Factory - Used to create objects./// </summary>publicclassPersonFactory{publicIPersonGetPerson(PersonTypetype){switch(type){casePersonType.Rural:returnnewVillager();casePersonType.Urban:returnnewCityPerson();default:thrownewNotSupportedException();}}}

In the above code you can see the creation of one interface called IPerson and two implementations called Villager and CityPerson. Based on the type passed into the PersonFactory object, we are returning the original concrete object as the interface IPerson.

A factory method is just an addition to PersonFactory 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.

publicinterfaceIProduct{stringGetName();boolSetPrice(doubleprice);}publicclassPhone:IProduct{privatedouble_price;publicstringGetName(){return"Apple TouchPad";}publicboolSetPrice(doubleprice){_price=price;returntrue;}}/* Almost same as Factory, just an additional exposure to do something with the created method */publicabstractclassProductAbstractFactory{protectedabstractIProductMakeProduct();publicIProductGetObject()// Implementation of Factory Method.{returnthis.MakeProduct();}}publicclassPhoneConcreteFactory:ProductAbstractFactory{protectedoverrideIProductMakeProduct(){IProductproduct=newPhone();// Do something with the object after you get the object.product.SetPrice(20.30);returnproduct;}}

You can see we have used MakeProduct in concreteFactory. As a result, you can easily call MakeProduct() from it to get the IProduct. 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

This Java example is similar to one in the book Design Patterns.

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:

publicabstractclassRoom{abstractvoidconnect(Roomroom);}publicclassMagicRoomextendsRoom{publicvoidconnect(Roomroom){}}publicclassOrdinaryRoomextendsRoom{publicvoidconnect(Roomroom){}}publicabstractclassMazeGame{privatefinalList<Room>rooms=newArrayList<>();publicMazeGame(){Roomroom1=makeRoom();Roomroom2=makeRoom();room1.connect(room2);rooms.add(room1);rooms.add(room2);}abstractprotectedRoommakeRoom();}

In the above snippet, the MazeGame constructor is a template method that makes some common logic. It refers to the makeRoom 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 makeRoom method:

publicclassMagicMazeGameextendsMazeGame{@OverrideprotectedMagicRoommakeRoom(){returnnewMagicRoom();}}publicclassOrdinaryMazeGameextendsMazeGame{@OverrideprotectedOrdinaryRoommakeRoom(){returnnewOrdinaryRoom();}}MazeGameordinaryGame=newOrdinaryMazeGame();MazeGamemagicGame=newMagicMazeGame();

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).

/* Factory and car interfaces */interfaceCarFactory{publicfunctionmakeCar():Car;}interfaceCar{publicfunctiongetType():string;}/* Concrete implementations of the factory and car */classSedanFactoryimplementsCarFactory{publicfunctionmakeCar():Car{returnnewSedan();}}classSedanimplementsCar{publicfunctiongetType():string{return'Sedan';}}/* Client */$factory=newSedanFactory();$car=$factory->makeCar();print$car->getType();

Python

Same as Java example.

fromabcimportABC,abstractmethodclassMazeGame(ABC):def__init__(self)->None:self.rooms=[]self._prepare_rooms()def_prepare_rooms(self)->None:room1=self.make_room()room2=self.make_room()room1.connect(room2)self.rooms.append(room1)self.rooms.append(room2)defplay(self)->None:print(f"Playing using {self.rooms[0]}")@abstractmethoddefmake_room(self):raiseNotImplementedError("You should implement this!")classMagicMazeGame(MazeGame):defmake_room(self)->"MagicRoom":returnMagicRoom()classOrdinaryMazeGame(MazeGame):defmake_room(self)->"OrdinaryRoom":returnOrdinaryRoom()classRoom(ABC):def__init__(self)->None:self.connected_rooms=[]defconnect(self,room:"Room")->None:self.connected_rooms.append(room)classMagicRoom(Room):def__str__(self)->str:return"Magic room"classOrdinaryRoom(Room):def__str__(self)->str:return"Ordinary room"ordinaryGame=OrdinaryMazeGame()ordinaryGame.play()magicGame=MagicMazeGame()magicGame.play()

Uses

See also

Related Research Articles

In object-oriented programming, a class is an extensible program-code-template for creating objects, providing initial values for state and implementations of behavior.

A visitor pattern is a software design pattern that separates the algorithm from the object structure. Because of this separation new operations can be added to existing object structures without modifying the structures. It is one way to follow the open/closed principle in object-oriented programming and software engineering.

<i>Design Patterns</i> 1994 software engineering book

Design Patterns: Elements of Reusable Object-Oriented Software (1994) is a software engineering book describing software design patterns. The book was written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, with a foreword by Grady Booch. The book is divided into two parts, with the first two chapters exploring the capabilities and pitfalls of object-oriented programming, and the remaining chapters describing 23 classic software design patterns. The book includes examples in C++ and Smalltalk.

<span class="mw-page-title-main">Abstract factory pattern</span> Software design pattern

The abstract factory pattern in software engineering is a design pattern that provides a way to create families of related objects without imposing their concrete classes, by encapsulating a group of individual factories that have a common theme without specifying their concrete classes. According to this pattern, a client software component creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the family. The client does not know which concrete objects it receives from each of these internal factories, as it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.

The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently", introduced by the Gang of Four. The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.

<span class="mw-page-title-main">Flyweight pattern</span> Software design pattern for objects

In computer programming, the flyweight software design pattern refers to an object that minimizes memory usage by sharing some of its data with other similar objects. The flyweight pattern is one of twenty-three well-known GoF design patterns. These patterns promote flexible object-oriented software design, which is easier to implement, change, test, and reuse.

The prototype pattern is a creational design pattern in software development. It is used when the types of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to avoid subclasses of an object creator in the client application, like the factory method pattern does, and to avoid the inherent cost of creating a new object in the standard way when it is prohibitively expensive for a given application.

In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other instances of the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern as well as to the Open-Closed Principle, by allowing the functionality of a class to be extended without being modified. Decorator use can be more efficient than subclassing, because an object's behavior can be augmented without defining an entirely new object.

In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method.

A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user.

In object-oriented programming such as is often used in C++ and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method that is dispatched dynamically. Virtual functions are an important part of (runtime) polymorphism in object-oriented programming (OOP). They allow for the execution of target functions that were not precisely identified at compile time.

In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or in added complexity to the design due to inflexibility in the creation procedures. Creational design patterns solve this problem by somehow controlling this object creation.

<span class="mw-page-title-main">Factory (object-oriented programming)</span> Object that creates other objects

In object-oriented programming, a factory is an object for creating other objects; formally, it is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be "new". More broadly, a subroutine that returns a "new" object may be referred to as a "factory", as in factory method or factory function. The factory pattern is the basis for a number of related software design patterns.

<i>Modern C++ Design</i> Book by Andrei Alexandrescu

Modern C++ Design: Generic Programming and Design Patterns Applied is a book written by Andrei Alexandrescu, published in 2001 by Addison-Wesley. It has been regarded as "one of the most important C++ books" by Scott Meyers.

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object or class, retaining similar implementation. Also defined as deriving new classes from existing ones such as super class or base class and then forming them into a hierarchy of classes. In most class-based object-oriented languages like C++, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object", with the exception of: constructors, destructors, overloaded operators and friend functions of the base class. Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors, to reuse code and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a directed acyclic graph.

In programming languages, an abstract type is a type in a nominative type system that cannot be instantiated directly; by contrast, a concrete typecan be instantiated directly. Instantiation of an abstract type can occur only indirectly, via a concrete subtype.

The curiously recurring template pattern (CRTP) is an idiom, originally in C++, in which a class X derives from a class template instantiation using X itself as a template argument. More generally it is known as F-bound polymorphism, and it is a form of F-bounded quantification.

In software engineering, a fluent interface is an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility by creating a domain-specific language (DSL). The term was coined in 2005 by Eric Evans and Martin Fowler.

In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior. The null object design pattern, which describes the uses of such objects and their behavior, was first published as "Void Value" and later in the Pattern Languages of Program Design book series as "Null Object".

References

  1. Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 121ff. ISBN   0-201-63361-2.
  2. Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (eds.). Head First Design Patterns (paperback). Vol. 1. O'REILLY. p. 162. ISBN   978-0-596-00712-6 . Retrieved 2012-09-12.
  3. "The Factory Method design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.
  4. Erich Gamma (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 123 ff. ISBN   0-201-63361-2.