Abstract Factory membuat keluarga object yang saling berkaitan tanpa menyebutkan class konkretnya. Cocok saat kamu punya beberapa "varian" produk yang harus konsisten (misal semua komponen UI bertema gelap, atau semua komponen UI bertema terang).
Problem yang diselesaikan:
Misalkan kamu bikin UI toolkit cross-platform. Di Windows, tombol tampil dengan style A, checkbox style B. Di macOS, tombol tampil dengan style C, checkbox style D. Kamu tidak mau aplikasi tiba-tiba menggabungkan tombol Windows dengan checkbox macOS — keluarga harus konsisten.
Tanpa pattern, client code akan penuh kondisi if (platform === "windows") ... di setiap tempat object dibuat. Abstract Factory memindahkan semua pilihan ini ke satu factory per varian, lalu client cukup tanya "bikinin aku button dan checkbox" — factory yang memastikan semuanya bertema sama.
Factory Method vs Abstract Factory:
- Factory Method — satu method bikin satu produk.
createButton(). - Abstract Factory — interface yang bikin beberapa produk berkaitan.
createButton()+createCheckbox()+createInput(), semua bertema sama.
Implementasi minimal (JS/TS):
// 1. Produk-produk abstract (kontrak)
class Button {
render() { throw new Error("abstract"); }
}
class Checkbox {
render() { throw new Error("abstract"); }
}
// 2. Varian konkret — keluarga "Dark"
class DarkButton extends Button {
render() { return "<button class='dark'>Click</button>"; }
}
class DarkCheckbox extends Checkbox {
render() { return "<input type='checkbox' class='dark'>"; }
}
// 3. Varian konkret — keluarga "Light"
class LightButton extends Button {
render() { return "<button class='light'>Click</button>"; }
}
class LightCheckbox extends Checkbox {
render() { return "<input type='checkbox' class='light'>"; }
}
// 4. Abstract Factory — interface yang bikin sekeluarga produk
class UIFactory {
createButton() { throw new Error("abstract"); }
createCheckbox() { throw new Error("abstract"); }
}
// 5. Concrete Factory — satu per varian
class DarkUIFactory extends UIFactory {
createButton() { return new DarkButton(); }
createCheckbox() { return new DarkCheckbox(); }
}
class LightUIFactory extends UIFactory {
createButton() { return new LightButton(); }
createCheckbox() { return new LightCheckbox(); }
}
// 6. Client — cukup terima factory, tidak tahu varian apa
function renderLoginForm(factory) {
const button = factory.createButton();
const checkbox = factory.createCheckbox();
return button.render() + checkbox.render();
// Keluarga dijamin konsisten: Dark-Dark atau Light-Light
}
const theme = localStorage.getItem("theme") === "dark"
? new DarkUIFactory()
: new LightUIFactory();
renderLoginForm(theme);
Pilihan varian hanya terjadi SEKALI di boot time, setelah itu client tinggal pakai factory.
Dunia nyata di ekosistem JS:
- Theme providers (Material UI, Chakra UI) —
<ThemeProvider theme={darkTheme}>menyediakan semua komponen UI (Button, Input, Card) bervarian sama. Yang di-inject via Context adalah konsep Abstract Factory: satu object yang bikin "keluarga styled components". - Database driver abstractions — Knex.js, Sequelize dialect adapter.
new Sequelize({dialect: "postgres"})internal pilih factory yang bikinPostgresQueryBuilder,PostgresColumnCompiler, dll. Semua konsisten untuk Postgres. - React Native platform-specific components —
Platform.select({ios: ..., android: ...})adalah bentuk ringan Abstract Factory.
Kapan pakai:
- Ada beberapa keluarga produk yang harus konsisten (UI theme, DB driver, OS-specific API)
- Client tidak perlu tahu varian mana yang dipakai
- Kamu ingin mudah tambah varian baru tanpa sentuh client code
Kapan JANGAN pakai:
- Hanya ada satu jenis produk — cukup Factory Method saja
- Varian jarang bertambah — pattern ini tambah class banyak, overkill untuk 1-2 varian yang stabil
- Di JS modern dengan config object sederhana sering cukup:
{theme: "dark", button: DarkButton, checkbox: DarkCheckbox}tanpa hierarchy class
Trade-off:
Kelebihannya: client loosely coupled ke produk konkret, konsistensi keluarga terjamin. Kekurangannya: banyak class (1 factory + N produk × M varian), dan menambah produk baru (misal Radio) mesti update semua factory — itu trade-off terbesar.