Ce este
Șablonul Abstract Factory creează familii întregi de obiecte înrudite, care merg împreună. Acolo unde un factory method face un singur produs, un abstract factory face 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
renderScreen primește orice UIFactory și construiește din el un ecran consecvent. Schimbarea întregului aspect înseamnă un singur argument — iar amestecarea temelor este imposibilă prin construcție.
O fabrică, o singură familie consecventă
Tema deschisă produce doar piese deschise, tema închisă doar piese închise. renderScreen nu se schimbă niciodată: apelează createLabel() și createButton() pe orice fabrică i-a fost dată.
Ieșire: program TypeScript și rezultatul capturat
interface Button {
render(): string
}
interface Label {
render(): string
}
// Fabrica abstractă creează o întreagă familie potrivită.
interface UIFactory {
createButton(): Button
createLabel(): Label
}
class LightButton implements Button {
render(): string {
return "[ OK ] buton deschis"
}
}
class LightLabel implements Label {
render(): string {
return "salut etichetă deschisă"
}
}
class DarkButton implements Button {
render(): string {
return "[ OK ] buton închis"
}
}
class DarkLabel implements Label {
render(): string {
return "salut etichetă închisă"
}
}
class LightTheme implements UIFactory {
createButton(): Button {
return new LightButton()
}
createLabel(): Label {
return new LightLabel()
}
}
class DarkTheme implements UIFactory {
createButton(): Button {
return new DarkButton()
}
createLabel(): Label {
return new DarkLabel()
}
}
function renderScreen(factory: UIFactory): void {
console.log(factory.createLabel().render())
console.log(factory.createButton().render())
}
renderScreen(new LightTheme())
renderScreen(new DarkTheme())
Când să îl folosești
Folosește-l atunci când mai multe obiecte trebuie să rămână consecvente între ele — teme, seturi de widget-uri specifice unei platforme, perechi potrivite de formate de import/export.
Renunță la el atunci când produsele nu trebuie să se potrivească. Obiectele independente merită constructori independenți, nu o fabrică de familie.
Avantaje și dezavantaje
Avantaje: consecvența familiei este garantată; familii întregi se schimbă cu o singură valoare; codul apelant depinde doar de interfețe.
Dezavantaje: foarte multe interfețe și clase pentru o treabă mică; adăugarea unui produs nou în familie înseamnă modificarea fiecărei fabrici.