Usefall

The Abstract Factory Pattern

Purpose

Things are created then other things are happening.

I want to change the kind of things that are created without affecting anything else.


Robo Merchant

I sell battle parts to Robots!

class RoboMerchant {
  sell(customer) {
    const eyes = new BattleRobotEyes();
    const mouth = new BattleRobotMouth();

    customer.buy(eyes, mouth);
  }
}

Roborto

I love Robotina but I can’t express my love with battle parts!

Do you have any parts to show my love?

Robo Merchant

Unfortuantely, I only make battle parts.

But I have always wanted to work with factories to expand the kind of parts I sell.

Hold on a second…

class RoboMerchant {
  sell(customer, factory) {
    const eyes = factory.makeEyes();
    const mouth = factory.makeMouth();

    customer.buy(eyes, mouth);
  }
}
class LovePartsFactory {
  makeEyes() {
    return new LoveRobotEyes();
  }
  makeMouth() {
    return new LoveRobotMouth();
  }
}
class BattlePartsFactory {
  makeEyes() {
    return new BattleRobotEyes();
  }
  makeMouth() {
    return new BattleRobotMouth();
  }
}

Robo Merchant

Alright, I am ready now.

Let’s give this a shot!

const roboMerchant = new RoboMerchant();
const customer = new Roborto();

const factory = customer.wantsLove
  ? new LovePartsFactory()
  : new BattlePartsFactory();

roboMerchant.sell(customer, factory);

Robo Merchant

There we go, how do you like your new parts?

Roborto

Just right! Thanks!!!

Robotina I love you!!!

Robotina

Awh I never knew! I love you too!!!


Solution

Make your code create what it needs by using a separate thing (an abstract factory).

Provide a different kind of factory that corresponds with the kind of things you want to create.


Credits and References