Summary
Pattern Name | Factory Pattern |
Pattern Type | Creational Pattern |
Scope | Class |
Other Names | Virtual Constructor |
Tagline | Generate objects based on selected criteria |
Use cases | 1. When we don’t know the type of object to be generated beforehand 2. When we want to generate the object on the fly based on some criteria |
Related Patterns | Abstract Factory Strategy Prototype |
Difficulty Level | Medium |
Implementations |
Definition
Factory pattern is one of the most popular and commonly used patterns. When we don’t know what type of object is going to be generated, then we use the Factory pattern to create objects based on some criteria.
Say, you have a few same types of classes and in your use case those classes can be used anytime anywhere, and you don’t want to restrict the usage of those classes by directly using a new operator, then factory pattern comes into play.
Factory pattern prevents class instantiation in the code directly, instead, it lets a factory class generate the desired item objects. Also, this pattern hides the complexity of generating objects from the client, the client is unaware of how the objects are being generated. This pattern implies loose coupling by reducing the dependency of the application on any concrete classes.
As the same interface is used to ensure a uniform interface for the underlying item objects, so the implementations of the classes can be changed easily. Also, the object generation process is in the same place, so that logic can be changed easily(without any side-effect) if required.
There are 2 variations of Factory pattern implementation.
Check the implementations below.
Factory Implementation
In the simple factory implementation, we use one factory class to generate all the object(s). A simple Factory pattern implementation has 3 elements.
- Item Interface: an interface that ensures the type of the Item Concrete classes.
- Item Concrete Classes: classes that implement the Item Interface. This implementation will be as per your requirement.
- Factory Class: a class that implements a function, which will return instances of Item Concrete classes based on some criteria.
Follow the steps below to implement the factory pattern.
- Create an interface that will be used to ensure the same type for the concrete item classes.
- Create concrete item classes, and implement the interface. Write the definition of the required functions. This implementation will be as per your requirement.
- Create a factory class. create a function that accepts a param to identify which object to return and the return type of the function will be of the Item interface.
- In the function return instance of the Item class based on some condition.
- In the client create an instance of the factory class.
- Call the factory class function to get instances of Item classes.
- Now the instance of the Item class.
Let’s take a look at examples.
Factory Example
Let’s take the example of a transport system.
General Interface for Item Classes
Let’s create an interface named Transport.
- This will be implemented by other transport classes, which will ensure the same interface for all transport item classes.
- A few methods are declared here in the interface, these are not fixed. You can declare methods as you need in the transport classes.
interface Transport
start()
stop()
repair()
end interface
Concrete Item Classes
- Create concrete classes that represent the transports. All these classes implement the Transport interface.
- Here we have classes for Bike, Car and Plane.
// Bike class
class Bike implements Transport
function start()
print("Bike started")
end function
function stop()
print("Bike Stopped")
end function
function repair()
print("Bike Repair")
end function
end class
// Car class
class Car implements Transport
function start()
print("Car started")
end function
function stop()
print("Car Stopped")
end function
function repair()
print("Car Repair")
end function
end class
// Plane class
class Plane implements Transport
function start()
print("Plane started")
end function
function stop()
print("Plane Stopped")
end function
function repair()
print("Plane Repair")
end function
end class
Factory Class
Then we need to create a class that will be used as a factory. Let’s name it TransportFactory.
- In the class we have to create a method that will take some identifier as param and will return an object of type transport. We named the method getTransport here, this can have any name, there is no strict rule, but in lots of places this will be named as getInstance.
- Our getTransport method takes a string as param. If the param is one of “bike”, “car”, and “plane” then this method will create a relevant object and return it. If the type does not match these defined types, then the method will return null.
class TransportFactory
function getTransport(type: String): Transport
if (type == "bike")
return new Bike()
end if
if (type == "car")
return new Car()
end if
if (type == "plane")
return new Plane()
end if
return null
end function
end class
Demo
For checking the implementation – create an instance of TransportFactory. Then call the getTransport method and pass the string which indicates the object.
var transportFactory: TransportFactory = new TransportFactory()
var transport1: Transport = transportFactory.getTransport("bike")
transport1.start()
var transport2: Transport = transportFactory.getTransport("car")
transport2.start()
var transport3: Transport = transportFactory.getTransport("plane")
transport3.start()
Output
The above demo code will generate the output as below.
Bike started
Car started
Plane started
Factory Method Implementation
Factory method comes into play when you want to move the creation of object parts to different factory sub-classes.
A Factory Method implementation has 4 elements.
- Item Interface: interface to ensure the same type of Item Concrete classes.
- Item Concrete Classes: concrete classes that implement the Item interface. These implementations will be as per the requirement, there is no strict rule for this implementation.
- Factory Abstract Class: abstract class that declares a function to get Item Concrete class instance from Factory Sub-Classes. There can be other functions for using the instance.
- Factory Sub-Classes: implement the Factory and returns instance based on some criteria.
Let’s take a look at an example.
Factory Method Example
Let’s take the example of a transport system.
General Interface for Item Classes
- Interface to ensure a common interface for the item classes.
- There is no specific rule for this interface. This can be defined according to the requirement.
interface Transport
start()
stop()
repair()
end interface
Road Transport Concrete Item Classes
- Main item classes for road transports, which we want to generate finally using the Factory method.
- All these item classes implement the transport interface.
// Bus class
class Bus implements Transport
function start()
print("Bus started")
end function
function stop()
print("Bus Stopped")
end function
function repair()
print("Bus Repair")
end function
end class
// Bike class
class Bike implements Transport
function start()
print("Bike started")
end function
function stop()
print("Bike Stopped")
end function
function repair()
print("Bike Repair")
end function
end class
// Car class
class Car implements Transport
function start()
print("Car started")
end function
function stop()
print("Car Stopped")
end function
function repair()
print("Car Repair")
end function
end class
Air Transport Concrete Item Classes
- Main item classes for air transports, which we want to generate finally using the Factory method.
- These classes implement the transport interface.
// Plane class
class Plane implements Transport
function start()
print("Plane started")
end function
function stop()
print("Plane Stopped")
end function
function repair()
print("Plane Repair")
end function
end class
// Helicopter class
class Helicopter implements Transport
function start()
print("Helicopter started")
end function
function stop()
print("Helicopter Stopped")
end function
function repair()
print("Helicopter Repair")
end function
end class
Factory Classes
- TransportFactory is an abstract class, that ensures a common interface for the factory classes.
- Factory classes for road and air item classes are also declared here. These factory classes will be used to generate objects of the relevant type.
// Transport Factory abstract class
abstract class TransportFactory
function operateTransport(String name)
var transport: Transport = getTransport(name)
transport.start()
transport.stop()
end function
function repairTransport(name: String)
Transport transport = getTransport(name)
transport.repair()
end function
abstract function getTransport(name: String): Transport
end class
// Road transport factory
class RoadTransportFactory extends TransportFactory
function getTransport(name: String): Transport
if (name == "car")
return new Car()
end if
if (name == "bike")
return new Bike()
end if
if (name == "bus")
return new Bus()
end if
return null
end function
end class
// Air transport factory
class AirTransportFactory extends TransportFactory
function getTransport(name: String): Transport
if (name == "plane")
return new Plane()
end if
if (name == "helicopter")
return new Helicopter()
end if
return null
end function
end class
Demo
- For the demo, we can generate objects of the factory classes.
- We can use factory objects of different types, and pass relevant identifiers to determine which object generate.
- Call the methods defined in the TransportFactory abstract class for performing the operations.
var roadTransportFactory: TransportFactory = new RoadTransportFactory()
var airTransportFactory: TransportFactory = new AirTransportFactory()
roadTransportFactory.operateTransport("bus")
airTransportFactory.operateTransport("helicopter")
roadTransportFactory.repairTransport("bike")
Output
We will get the following output for the above demo code.
Bus started
Bus Stopped
---------------------------------------
Helicopter started
Helicopter Stopped
---------------------------------------
Bike Repair
Code Implementations
Use the following links to check Factory pattern implementation in specific programming languages.