Skip to content
LLD Learn/Creational Patterns
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Factory Method & Abstract Factory

7 min read

You'll learn to

  • -Use Factory Method to defer object creation to subclasses without the caller knowing the concrete type
  • -Use Abstract Factory to produce families of related objects, and explain when it earns its extra layer over a plain factory

Both patterns solve the same root problem - decoupling the code that needs an object from the code that decides which concrete class to instantiate - but at different scopes. Factory Method produces one product; Abstract Factory produces a whole family of related products that need to stay consistent with each other.

Factory Method: One Product, Deferred to Subclasses

Factory Method defines a method for creating an object, but lets subclasses decide which concrete class to instantiate. A DocumentCreator base class might declare create_document(), with PDFCreator and WordCreator subclasses each returning their own concrete Document type - callers work against DocumentCreator and never need an if/elif on document type.

Factory Method - the decision lives in a subclass
class DocumentCreator(ABC):
    @abstractmethod
    def create_document(self) -> Document: ...

    def export(self) -> None:                # uses the factory method, doesn't know the concrete type
        doc = self.create_document()
        doc.save()

class PDFCreator(DocumentCreator):
    def create_document(self) -> Document:
        return PDFDocument()

class WordCreator(DocumentCreator):
    def create_document(self) -> Document:
        return WordDocument()

Abstract Factory: Families That Must Stay Consistent

Abstract Factory earns its extra layer when you are creating several related objects that must be mutually compatible - a UI toolkit that needs a Button, Checkbox, and ScrollBar that are all either consistently "dark theme" or consistently "light theme," never a mismatched mix. A single factory interface exposes create_button(), create_checkbox(), and create_scrollbar(), and each concrete factory (DarkThemeFactory, LightThemeFactory) guarantees every product it returns belongs to the same family.

Abstract Factory - one factory guarantees a consistent family
class UIFactory(ABC):
    @abstractmethod
    def create_button(self) -> Button: ...
    @abstractmethod
    def create_checkbox(self) -> Checkbox: ...

class DarkThemeFactory(UIFactory):
    def create_button(self) -> Button: return DarkButton()
    def create_checkbox(self) -> Checkbox: return DarkCheckbox()

class LightThemeFactory(UIFactory):
    def create_button(self) -> Button: return LightButton()
    def create_checkbox(self) -> Checkbox: return LightCheckbox()

def render_form(factory: UIFactory):
    # can never accidentally mix a DarkButton with a LightCheckbox
    button, checkbox = factory.create_button(), factory.create_checkbox()

The interview tell for "do I need Abstract Factory, or is Factory Method enough": ask whether the products need to be consistent as a set. If there is only ever one product type being created, Abstract Factory's extra layer is unjustified complexity.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

ScaleDojo Logo
Initializing ScaleDojo