Ce este
Șablonul Fabrica abstractă (Abstract Factory) creează familii întregi de obiecte înrudite, care trebuie folosite împreună. Acolo unde o metodă fabrică produce un singur produs, o fabrică abstractă produce un set potrivit — și garantează că piesele nu sunt niciodată amestecate.
Cazul clasic este tematizarea: o temă deschisă trebuie să producă butoane deschise și etichete deschise, niciodată un amestec.
Exemplu: o fabrică de teme
render_screen primește orice UIFactory și construiește din ea un ecran consecvent. Schimbarea întregului aspect înseamnă un singur argument — iar amestecarea temelor este imposibilă prin construcție.
O fabrică, o familie consecventă
Tema deschisă produce doar piese deschise, tema întunecată doar piese întunecate. render_screen nu se schimbă niciodată.
Ieșire: program Python complet
from typing import Protocol
class Button(Protocol):
def render(self) -> str: ...
class Label(Protocol):
def render(self) -> str: ...
# Fabrica abstractă produce o familie întreagă de piese potrivite.
class UIFactory(Protocol):
def new_button(self) -> Button: ...
def new_label(self) -> Label: ...
class LightButton:
def render(self) -> str:
return "[ OK ] buton deschis"
class LightLabel:
def render(self) -> str:
return "hello etichetă deschisă"
class DarkButton:
def render(self) -> str:
return "[ OK ] buton întunecat"
class DarkLabel:
def render(self) -> str:
return "hello etichetă întunecată"
class LightTheme:
def new_button(self) -> Button:
return LightButton()
def new_label(self) -> Label:
return LightLabel()
class DarkTheme:
def new_button(self) -> Button:
return DarkButton()
def new_label(self) -> Label:
return DarkLabel()
def render_screen(factory: UIFactory) -> None:
print(factory.new_label().render())
print(factory.new_button().render())
render_screen(LightTheme())
render_screen(DarkTheme())
Când să-l folosești
Folosește-l când mai multe obiecte trebuie să rămână consecvente între ele — teme, seturi de componente grafice pentru platforme, perechi potrivite de formate de import/export.
Renunță la el când produsele nu trebuie să se potrivească. Obiectele independente merită constructori independenți, nu o fabrică de familii.
Avantaje și dezavantaje
Avantaje: consecvența familiei este garantată; familii întregi se schimbă cu o singură valoare; codul apelant depinde doar de protocoale.
Dezavantaje: multe protocoale și clase pentru o sarcină mică; adăugarea unui nou produs în familie înseamnă modificarea fiecărei fabrici.