Tags

  • AWS (7)
  • Apigee (3)
  • ArchLinux (5)
  • Array (6)
  • Backtracking (6)
  • BinarySearch (6)
  • C++ (19)
  • CI&CD (3)
  • Calculus (2)
  • DesignPattern (43)
  • DisasterRecovery (1)
  • Docker (8)
  • DynamicProgramming (20)
  • FileSystem (11)
  • Frontend (2)
  • FunctionalProgramming (1)
  • GCP (1)
  • Gentoo (6)
  • Git (15)
  • Golang (1)
  • Graph (10)
  • GraphQL (1)
  • Hardware (1)
  • Hash (1)
  • Kafka (1)
  • LinkedList (13)
  • Linux (27)
  • Lodash (2)
  • MacOS (3)
  • Makefile (1)
  • Map (5)
  • MathHistory (1)
  • MySQL (21)
  • Neovim (10)
  • Network (66)
  • Nginx (6)
  • Node.js (33)
  • OpenGL (6)
  • PriorityQueue (1)
  • ProgrammingLanguage (9)
  • Python (10)
  • RealAnalysis (20)
  • Recursion (3)
  • Redis (1)
  • RegularExpression (1)
  • Ruby (19)
  • SQLite (1)
  • Sentry (3)
  • Set (4)
  • Shell (3)
  • SoftwareEngineering (12)
  • Sorting (2)
  • Stack (4)
  • String (2)
  • SystemDesign (13)
  • Terraform (2)
  • Tree (24)
  • Trie (2)
  • TwoPointers (16)
  • TypeScript (3)
  • Ubuntu (4)
  • Home

    [Creational] Abstract Factory

    Published Apr 27, 2022 [  DesignPattern  ]

    Real world example

    Extending our door example from Simple Factory. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc.

    In plain words

    A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.

    Wikipedia says

    The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes

    Programmatic Example

    Translating the door example above. First of all we have our Door interface and some implementation for it

    interface Door {
        getDescription();
    }
    
    class WoodenDoor implements Door {
        getDescription() {
            console.log('I am a wooden door')
        }
    }
    
    class IronDoor implements Door {
        getDescription() {
            console.log('I am a iron door')
        }
    }
    

    Then we have some fitting experts for each door type

    interface DoorFittingExpert {
        getDescription();
    }
    
    class Welder implements DoorFittingExpert {
        getDescription() {
            console.log('I can only fit iron doors')
        }
    }
    
    class Carpenter implements DoorFittingExpert {
        getDescription() {
            console.log('I can only fit wooden doors')
        }
    }
    

    Now we have our abstract factory that would let us make family of related objects i.e. wooden door factory would create a wooden door and wooden door fitting expert and iron door factory would create an iron door and iron door fitting expert

    interface DoorFactory {
        makeDoor(): Door;
        makeFittingExpert(): DoorFittingExpert;
    }
    
    class WoodenDoorFactory implements DoorFactory {
        makeDoor(): Door {
            return new WoodenDoor()
        }
        makeFittingExpert(): DoorFittingExpert {
            return new Carpenter()
        }
    }
    
    class IronDoorFactory implements DoorFactory {
        makeDoor(): Door {
            return new IronDoor();
        }
        makeFittingExpert(): DoorFittingExpert {
            return new Welder()
        }
    }
    

    And then it can be used as

    // wooden
    const woodenFactory = new WoodenDoorFactory()
    let door = woodenFactory.makeDoor();
    let expert = woodenFactory.makeFittingExpert()
    door.getDescription()
    expert.getDescription()
    
    // iron
    const ironFactory = new IronDoorFactory()
    door = ironFactory.makeDoor()
    expert = ironFactory.makeFittingExpert()
    door.getDescription()
    expert.getDescription()
    

    As you can see the wooden door factory has encapsulated the carpenter and the wooden door also iron door factory has encapsulated the iron door and welder. And thus it had helped us make sure that for each of the created door, we do not get a wrong fitting expert.

    When to use?

    When there are interrelated dependencies with not-that-simple creation logic involved

    References