The Factory Method
Software Design Fables
Imagine code that creates a thing and then does something with the created thing.
- Creating that thing may be complex and not the main concern or responsibility of your task.
- It's inflexible if you are stuck with exclusively creating that one thing with no room for alterations.
Trade Offer
If you:
- Dedicate object creation to a separate method that acts as a factory for creating what you want.
You will:
- Enable children of your class to define their own custom creation behaviour by overriding the factory method while still benefitting from other methods defined in the parent.
- Keep your logic focused and clean with well defined responsibilities.
The Stubborn Duck Summoner
Chapter 1
👴 Narrator:
Once there was a summoner, a master of ducks.
His dreams were grand, but his ducks... weren't.
class StubbornDuckSummoner {
orderCreatureToAttack(): void {
const duck = new Duck();
duck.attack();
}
}
class Duck {
attack() {
console.log(`QUACK!`);
}
}
🧙 Eric The Stubborn Duck Summoner:
I am the duck summoner.
I exclusively summon ducks and order them to attack.
There is no need for any other creature!
My noble ducks are simply the best!
I shall defeat the Evil King!
class EvilKing {
/** Just exists for plot */
}
👴 Narrator:
Eric confronted the evil king with this duck.
const eric = new StubbornDuckSummoner();
const michael = new EvilKing();
eric.orderCreatureToAttack();
🦆 Duck:
I will mess you up!
🤴 Evil King:
A duck? Are you serious bro? 😒
Pathetic...🤣
🧙 Eric The Stubborn Duck Summoner:
Fate mocks me. These ducks are too weak!
I have been stubborn,
stuck in my old ways with these ducks.I must change...
Chapter 2
👴 Narrator:
Eric was stuck with his ducks.
Not even his children could summon anything other than ducks.
🧙 Eric The Stubborn Duck Summoner:
How can I change...
Right now I only know one abilityorderCreatureToAttack()
...
💡 My ability is actually doing two things...
First, It summons a creature.
Second, It orders that creature to attack my enemies.
If I dedicate creature summoning to a separate new abilitysummonCreature()
,
Then this would allow my children to override the creature being summoned.
And they would still have access to theorderCreatureToAttack()
abilitiy.
abstract class ReformedSummoner {
abstract summonCreature(): Creature;
orderCreatureToAttack(): void {
const creature = this.summonCreature();
creature.attack();
}
}
interface Creature {
attack: () => void;
}
👴 Narrator:
Thus, Eric became a flexible abstract creator.
His creation formerly the duck, is an abstract creature as well.
He had gained the power of the factory method.His children can now reap the benefits,
by overriding his factory methodsummonCreature()
and choosing aCreature
of their liking.
They also gainedorderCreatureToAttack()
through their inheritance
🥷 Bernard, son of the Duck Summoner:
My creature of choice is the
Dragon
class Dragon implements Creature {
attack() {
console.log("BREATHES FIRE!");
}
}
class DragonSummoner extends ReformedSummoner {
summonCreature(): Dragon {
return new Dragon();
}
}
👩 Addie, Daughter of the Duck Summoner:
My creature of choice is the
Phoenix
class Phoenix implements Creature {
attack() {
console.log("SOLAR FLARE");
}
}
class PhoenixSummoner extends ReformedSummoner {
summonCreature(): Phoenix {
return new Phoenix();
}
}
👴 Narrator:
Together, they confronted the Evil King, one last time.
const Bernard = new DragonSummoner();
const Adie = new PhoenixSummoner();
const Michael = new Enemy();
Bernard.orderCreatureToAttack();
// The sky darkens as a massive dragon emerges from the clouds...
Adie.orderCreatureToAttack();
// The air itself ignites with divine light of a great phoenix...
console.log(
"Michael: WHAT?! IMPOSSIBLE! Ducks don't breathe fire or... whatever that was!"
);
console.log("Bernard: Father's technique...");
console.log("Adie: ...but our creatures!");
console.log(
"Michael: NO! NO! The duck summoner's children... TOO STRONG! *dramatically disintegrates*"
);
console.log(
"Somewhere in the afterlife, the Old Duck Summoner smiles proudly."
);
🤴 Evil King:
WHAT?! IMPOSSIBLE!
Ducks don't breathe fire or... whatever that was!
Children of the Duck Summoner
We have inherited and customized our fathers
orderCreatureToAttack
by overriding his newsummonCreature
ability. BEHOLD OUR POWER!!!