Singleton Pattern memastikan sebuah class hanya punya satu instance di seluruh aplikasi, dan menyediakan akses global ke instance tersebut.
Analogi: Presiden suatu negara. Hanya ada 1 presiden aktif pada satu waktu. Semua orang merujuk ke presiden yang sama.
Masalah yang diselesaikan:
- Beberapa bagian kode butuh akses ke resource yang sama (database connection, config, cache)
- Membuat banyak instance akan memboroskan memory atau menyebabkan konflik
- Perlu satu sumber kebenaran (single source of truth)
Implementasi di JavaScript:
class Database {
constructor() {
if (Database.instance) {
return Database.instance;
}
this.connection = "postgresql://localhost:5432/mydb";
this.queries = [];
Database.instance = this;
}
query(sql) {
this.queries.push(sql);
console.log(`Executing: ${sql}`);
return { rows: [] };
}
getStats() {
return { totalQueries: this.queries.length };
}
}
const db1 = new Database();
const db2 = new Database();
console.log(db1 === db2); // true — sama persis!
db1.query("SELECT * FROM users");
console.log(db2.getStats()); // { totalQueries: 1 }
Cara lebih sederhana — Module Singleton:
// config.js — ES Module otomatis singleton!
let instance = null;
function createConfig() {
return {
apiUrl: "https://api.example.com",
timeout: 5000,
debug: false
};
}
export function getConfig() {
if (!instance) {
instance = createConfig();
}
return instance;
}
Di JavaScript, ES Modules sudah singleton by default. Saat kamu import module, Node.js meng-cache hasilnya. Import kedua kali mendapat object yang sama.
// logger.js
const logs = [];
export function log(msg) { logs.push(msg); console.log(msg); }
export function getLogs() { return [...logs]; }
// file-a.js
import { log } from "./logger.js";
log("dari file A");
// file-b.js
import { getLogs } from "./logger.js";
console.log(getLogs()); // ["dari file A"] — shared state!
Singleton di dunia nyata:
- Redux store — satu store untuk seluruh aplikasi
- Database connection pool — satu pool di-share semua request
- Logger — satu instance untuk consistent logging
- Cache — satu cache store untuk seluruh aplikasi
Peringatan:
- Singleton bisa membuat testing sulit (global state susah di-reset)
- Bisa jadi "global variable terselubung"
- Di JavaScript modern, module scope seringkali cukup — tidak perlu class Singleton
- Gunakan hanya untuk resource yang memang harus tunggal