Table of contents
Chapter 6 of the Domain Driven Design book talks about the life cycle of complex objects. In the last article I wrote about aggregates. Now let's move to the second design pattern which is factory design pattern. I will use java in this example.
What is a Factory?
A factory is a class whose sole responsibility is creating other objects. All the objects created by the factory implement an interface but are of different types.
Why use a Factory?
According to the book, you use a factory to separate the creation of objects from the logic. The author stresses that objects should be created using a factory but in my opinion you only need a factory if 2 conditions are satisfied:
- You actually have multiple types that can be represented as an interface
- The language you use supports polymorphism because otherwise, you gain nothing from implementing a factory
Example
Let's assume that we have a delivery system where we can deliver by a truck or by a ship. We can implement a class for the truck and a class for the ship where each class has a function deliver()
but then we will need to differentiate between them in the code probably by using if statements everywhere where we make a delivery.
But we can abstract that by creating a single interface that both classes can implement. Let's create an interface Shipment
that has a deliver
function:
interface Shipment
{
// ...
void deliver();
// ...
}
Then we can create 2 classes for our shipment types:
class Truck implements Shipment {
// ...
public void deliver() {
// Deliver using a truck
}
// ...
}
class Ship implements Shipment {
// ...
public void deliver() {
// Deliver using a ship
}
// ...
}
Now let's implement the factory class:
class ShipmentFactory {
public Shipment createShipment(string type) {
if (type.equals("ship")) {
return new Ship();
}
if (type.equals("truck")) {
return new Truck();
}
}
}
The factory class has a method createShipment
which takes a type as a string and returns either a ship or a truck according to the type. Notice that the method returns a Shipment
which is our interface. We can do that because java supports polymorphism which means that we can use the interface as a type and any class that implements the interface will fit in that type.
This also means that any other class doesn't need to know the type of the shipment and they can just use the interface and call the deliver
method directly on the interface without needing to make the distinction between the delivery methods the system supports.
Conclusion
The factory design pattern is useful but it is needed in specific cases and it cannot necessarily be implemented with any language. So you might not need it at all and you might not be able to make full use of it if the language you're using doesn't support polymorphism and maybe you're not using an OOP language in the first place.
In short, Factory design pattern is a good tool to have but you don't need to apply it everywhere.