Design Pattern in Action(1)

A series of programming design patterns illustration with examples with JavaScript/Python

Photo by Jezael Melgoza on Unsplash

Creational Pattern — Factory

Simply put, the factory pattern wraps creation (normally through class constructor) of different types of objects with a simple API instead of multiple if..else statement.

This comes in handy when you want to group several Classes under one API interface for abstraction. It demonstrates in Dynamic programming where the type of objects is decided at runtime.

But be careful with overuse it, as a lot of use cases can be solved simply using Dependency Injection.

See below with an example is in Python. Note the use of ABCMeta Classe to define an agreed interface among child classes.

from abc import ABCMeta, abstractmethod


class IBread(metaclass=ABCMeta):
@staticmethod
@abstractmethod
def make_bread():
pass


class Sourdough(IBread):
def __init__(self, quantity):
self.name = "Sourdough"
self.quantity = quantity

def make_bread(self):
return 'Making {0} of {1}!'.format(self.quantity, self.name)


class Ciabatta(IBread):
def __init__(self, quantity):
self.name = "Ciabatta"
self.quantity = quantity

def make_bread(self):
return 'Making {0} of {1}!'.format(self.quantity, self.name)


class BreadFactory:
@ staticmethod
def produce_bread(bread_type, quantity):
if bread_type == 'Ciabatta':
return Ciabatta(quantity)
if bread_type == 'Sourdough':
return Sourdough(quantity)
return None


sourdough = BreadFactory().produce_bread('Sourdough', 5)
sourdough.make_bread()
#Making 5 of Sourdough!

And this is the JavaScript equivalent:

let breadFactoryWarehouse = {};

breadFactoryWarehouse["Ciabatta"] = class Ciabatta {
constructor(quantity) {
this.quantity = quantity;
}
makeBread() {
return `Making ${this.quantity} of Ciabatta!`;
}
};

breadFactoryWarehouse["Sourdough"] = class Sourdough {
constructor(quantity) {
this.quantity = quantity;
}

makeBread() {
return `Making ${this.quantity} of Sourdough!`;
}
};

class BreadFactory {
constructor(type, quantity) {
return new breadFactoryWarehouse[type](quantity);
}
}

const sourdough = new BreadFactory("Sourdough", 5);
sourdough.makeBread;
#Making 5 of Sourdough!

Note that we are not using a if..else statement in the JavaScript implementation. This is a refactor for “open for extension” principle, just in case in the future more bread types will be added, we don’t need to go modify the BreadFactory itself, but just register the new bread type with breadFactoryWarehouse.

That’s pretty much of it!

Happy Reading!

Hi :)