Sobes.tech
Junior — Middle

Can you explain the principle of operation and purpose of the 'Abstract Factory' pattern in software design?

sobes.tech AI

Answer from AI

The "Abstract Factory" pattern is used to create families of related objects without specifying their concrete classes. It defines an interface for creating objects, allowing client code to work with different families of products without depending on their specific implementations.

For example, if you have an application that needs to work with different interface themes (light, dark), the abstract factory will allow creating the appropriate buttons and windows for each theme without changing the code that uses them.

Example in Python:

from abc import ABC, abstractmethod

# Abstract products
class Button(ABC):
    @abstractmethod
    def paint(self):
        pass

class Checkbox(ABC):
    @abstractmethod
    def paint(self):
        pass

# Concrete products for light theme
class LightButton(Button):
    def paint(self):
        print("Drawing light button")

class LightCheckbox(Checkbox):
    def paint(self):
        print("Drawing light checkbox")

# Concrete products for dark theme
class DarkButton(Button):
    def paint(self):
        print("Drawing dark button")

class DarkCheckbox(Checkbox):
    def paint(self):
        print("Drawing dark checkbox")

# Abstract factory
class GUIFactory(ABC):
    @abstractmethod
    def create_button(self) -> Button:
        pass

    @abstractmethod
    def create_checkbox(self) -> Checkbox:
        pass

# Concrete factories
class LightFactory(GUIFactory):
    def create_button(self) -> Button:
        return LightButton()

    def create_checkbox(self) -> Checkbox:
        return LightCheckbox()

class DarkFactory(GUIFactory):
    def create_button(self) -> Button:
        return DarkButton()

    def create_checkbox(self) -> Checkbox:
        return DarkCheckbox()

# Client code

def client_code(factory: GUIFactory):
    button = factory.create_button()
    checkbox = factory.create_checkbox()
    button.paint()
    checkbox.paint()

# Usage
client_code(LightFactory())
client_code(DarkFactory())

Thus, the pattern helps isolate product implementations and makes it easier to extend the program with new families of objects.