Design Pattern: Factory Pattern

Summary

Pattern NameFactory Pattern
Pattern Type Creational Pattern
Scope Class
Other NamesVirtual Constructor
TaglineGenerate objects based on selected criteria
Use cases1. 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 LevelMedium
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.

  1. Simple Factory Implementation
  2. Factory Method Implementation

Use Cases

Here are few use cases where we can use the Factory pattern-

When we want to centralize the object creation process(of a kind) in a single place.
Decouple object creation and usage.
When the object creation process is very complex, and we don’t want the client to be aware of the creation process.
When we need object caching or pooling, then we can do it in one place in the factory.

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.

  1. Item Interface: an interface that ensures the type of the Item Concrete classes.
  2. Item Concrete Classes: classes that implement the Item Interface. This implementation will be as per your requirements.
  3. Factory Class: a class that implements a function, which will return instances of Item Concrete classes based on some criteria.
Factory Pattern Implementation Diagram

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 requirements.
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()8
        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 a parameter 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 a 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

To check the implementation – create an instance of TransportFactory. Then call the getTransport method and pass the string that 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

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

  1. Item Interface: interface to ensure the same type of Item Concrete classes.
  2. 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.
  3. 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.
  4. 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 is generated.
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.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.