learnings

Factory method

Factory Method - is a creational design pattern that defines an interface for creating an object, but lets subclasses decide which class to instantiate. It promotes loose coupling by delegating object creation to a method, making the system more flexible and extensible.

This pattern is used when:

The pattern operates with four entities:

  1. Product - declares an interface for the objects the factory method creates
  2. Creator - declares the factory method that returns a Product
  3. ConcreteProduct - implements the Product interface
  4. ConcreteCreator - overrides the factory method to return an instance of a ConcreteProduct

Implementations

Python

from abc import ABC, abstractmethod


class Component(ABC):
    '''Product interface.'''

    @abstractmethod
    def install(self) -> None:
        ...

    @abstractmethod
    def specification(self) -> str:
        ...


class CPU(Component):
    def __init__(self, model: str, cores: int) -> None:
        self.model = model
        self.cores = cores

    def install(self) -> None:
        print(f'CPU {self.model} is installed into the socket')

    def specification(self) -> str:
        return f'{self.model}, {self.cores} cores'


class GPU(Component):
    def __init__(self, model: str, vram_mb: int) -> None:
        self.model = model
        self.vram_mb = vram_mb

    def install(self) -> None:
        print(f'GPU {self.model} is installed into the PCI-E slot')

    def specification(self) -> str:
        return f'{self.model}, {self.vram_mb} MB VRAM'


class RAM(Component):
    def __init__(self, model: str, capacity_gb: int) -> None:
        self.model = model
        self.capacity_gb = capacity_gb

    def install(self) -> None:
        print(f'RAM {self.model} is installed into the DIMM slot')

    def specification(self) -> str:
        return f'{self.model}, {self.capacity_gb} GB'


class ComponentFactory(ABC):
    '''Creator: declares the factory method.'''

    @abstractmethod
    def create_component(self) -> Component:
        ...

    def deliver(self) -> Component:
        '''Common operation that relies on the factory method.'''
        component = self.create_component()
        component.install()
        return component


class CPUFactory(ComponentFactory):
    def create_component(self) -> Component:
        return CPU(model='Ryzen 7 9800X3D', cores=8)


class GPUFactory(ComponentFactory):
    def create_component(self) -> Component:
        return GPU(model='GeForce RTX 5070', vram_mb=12288)


class RAMFactory(ComponentFactory):
    def create_component(self) -> Component:
        return RAM(model='DDR5-6000', capacity_gb=32)


def assemble_pc(factories: list[ComponentFactory]) -> None:
    print('Assembling PC:')
    for factory in factories:
        component = factory.deliver()
        print(f'  {component.specification()}')


def main() -> None:
    assemble_pc([CPUFactory(), GPUFactory(), RAMFactory()])


if __name__ == '__main__':
    main()