Summary
Pattern Name | Abstract Factory Pattern |
Pattern Type | Creational Pattern |
Scope | Object |
Other Names | Kit Super Factory |
Tagline | Factory of Factories |
Use cases | When we need a factory to generate multiple factory pattern implementations |
Related Patterns | Factory Facade Flyweight Prototype |
Difficulty Level | Medium |
Implementations |
Definition
Using the Factory pattern we generate objects based on some criteria. In Abstract factory pattern, we use multiple factory pattern implementations and generate objects based on that.
Consider this as a Factory that generates other Factories. So factory pattern works as a subset of this pattern implementation.
The purpose of Abstract Factory pattern is to create family/group of related/dependent objects, without depending on their concrete classes. Abstract Factory pattern also provides an encapsulation to the group of individual factories.
Abstract factory pattern is also called Factory of Factories, so before reading about Abstract Factory Pattern, take a look at the Factory Pattern.
Use Cases
- When we need to handle multiple factories.
- When an implementation needs to be independent of the creation and representation of the item classes.
- When the item classes have different groups/families and those are supposed to be used and handled together.
- When we want to release a package of item classes, but don’t want to reveal the implementation (Would disclose the interface only).
- When we want to easily interchange factory classes(from a bunch of factory classes).
Implementation
We need to implement multiple factory patterns and then implement a parent factory for those factory implementations.
There are 5 elements in the implementation:
- Abstract Factory Interface: interface that is implemented by concrete abstract factory classes.
- Concrete Abstract Factory Classes: classes that return instances of the concrete class.
- General Interface: interface implemented by concrete classes.
- Concrete Classes: classes implementing factory interface and containing the actual operations. Getting these classes is the final purpose of this implementation.
- Factory Producer: returns instances of concrete factory based on some pre-decided condition. Factory Producer directly uses only Abstract Factory Interface and Concrete Abstract Factory Classes.
Here is a diagram to represent the Abstract Factory Pattern implementation.
Here is how to implement Abstract Factory Pattern:
- First step is to create the classes that we want to use finally. These concrete classes are the main utility classes.
- Create an interface to standardize the utility classes.
- Implemented the interface to the utility classes.
- Create an interface for Abstract Factory and implement how the factory classes will be used to generate objects.
- Create multiple classes (as required) and implement Abstract factory and Use this parent factory to generate objects from the desired classes.
- Create a factory producer class, implement the condition to generate and return the factory class based on some conditions.
Examples
Example #1: Transport
Let’s take the example of a transport system. We have vehicles divided into 2 groups- Two wheelers and Four wheeler.
Take a look at the implementation.
Transport Factory Interface
Let’s create an interface for all the transport classes.
interface Transport
function start()
function stop()
function repair()
end interface
Transport Classes Implementing Transport Interface
Create transport item classes – Bicycle, Motorcycle, Car, Truck. All these classes implement the Transport interface.
// Bicycle class
class Bicycle implements Transport
function start()
print "Bicycle Started"
end function
function stop()
print "Bicycle Stopped"
end function
function repair()
print "Bicycle Repair"
end function
end class
// Motorcycle class
class Motorcycle implements Transport
function start()
print "Motorcycle Started"
end function
function stop()
print "Motorcycle Stopped"
end function
function repair()
print "Motorcycle 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
// Truck class
class Truck implements Transport
function start()
print "Truck Started"
end function
function stop()
print "Truck Stopped"
end function
function repair()
print "Truck Repair"
end function
end class
Abstract Transport Factory Interface
Let’s create an interface for the factory classes.
interface AbstractTransportFactory
function getTransport(type: String): Transport
end interface
Two-Wheel Transport Factory Class
Create a factory for two-wheeler vehicles and implement the AbstractTransportFactory interface.
class TwoWheelTransportFactory implements AbstractTransportFactory
fuction getTransport(String type): Transport
if (type == "bicycle")
return new Bicycle()
end if
if (type == "motorcycle")
return new Motorcycle()
end if
return null
end function
end class
Four-Wheel Transport Factory Class
Create a factory for four-wheeler vehicles and implement the AbstractTransportFactory interface.
class FourWheelTransportFactory implements AbstractTransportFactory
function getTransport(type: String): Transport
if (type == "car")
return new Car()
end if
if (type == "truck")
return new Truck()
end if
return null
end function
end class
Factory Producer Class
We need a class to generate those factory classes. Call that Factory Producer. This factory producer returns one of the above factories based on the number of wheels.
class FactoryProducer
static function getFactory(int numberOfWheels): AbstractTransportFactory
if (numberOfWheels == 2)
return new TwoWheelTransportFactory()
end if
if (numberOfWheels == 4)
return new FourWheelTransportFactory()
end if
return null
end function
end class
Demo
var transportFactory1: AbstractTransportFactory = FactoryProducer.getFactory(2)
Transport transport1 = transportFactory1.getTransport("bicycle")
transport1.start()
var transportFactory2: AbstractTransportFactory = FactoryProducer.getFactory(4)
Transport transport2 = transportFactory2.getTransport("truck")
transport2.start()
Output
Bicycle Started
Truck Started
Code Implementations
Use the following links to check Abstract Factory pattern implementation in specific programming languages.