Ce este
Șablonul Singleton se asigură că o clasă are exact o singură instanță în tot programul și le oferă tuturor același punct de acces la ea. Singleton-uri tipice: o configurație, un pool de conexiuni, un logger.
În TypeScript obținem acest lucru aproape gratuit. Un modul este încărcat și rulat o singură dată, iar tot ce creează el este păstrat în cache și partajat de fiecare import ulterior. Așadar, o valoare stocată la nivel de modul — inclusiv un câmp static al unei clase — există deja exact o singură dată. Șablonul adaugă doar două lucruri: un private constructor, astfel încât nimeni să nu poată construi un al doilea, și un accesor static care creează valoarea la prima utilizare.
Exemplu: o singură configurație pentru toți
Configurația este încărcată la primul apel Config.getInstance() și niciodată după aceea. Fiecare apelant primește același obiect.
Încarc-o o dată, păstreaz-o într-un câmp static
Linia „se încarcă configurația” se afișează o singură dată, deși Config.getInstance() este apelat de două ori — iar a === b dovedește că ambii apelanți dețin același obiect. Operatorul ??= atribuie doar atunci când câmpul este încă undefined, ceea ce înseamnă exact „creeaz-o prima dată”.
Ieșire: program TypeScript și rezultatul capturat
class Config {
readonly appName: string
// Privat: niciun cod din afara acestei clase nu poate construi un al doilea Config.
private constructor() {
console.log("se încarcă configurația (se întâmplă o singură dată)")
this.appName = "PromptCookbook"
}
// Singura instanță trăiește aici, creată la prima utilizare și păstrată pentru totdeauna.
private static instance: Config | undefined
static getInstance(): Config {
Config.instance ??= new Config()
return Config.instance
}
}
const a = Config.getInstance()
const b = Config.getInstance()
console.log("aplicație:", a.appName)
console.log("aceeași instanță:", a === b)
Când să îl folosești
Folosește-l atunci când chiar trebuie să existe un singur exemplar din ceva: o singură configurație încărcată, un singur pool de conexiuni, un singur cache — iar crearea lui este costisitoare sau duplicatele ar intra în conflict.
Renunță la el atunci când poți pur și simplu să creezi valoarea o dată la începutul programului și să o transmiți celor care au nevoie de ea. Transmiterea deschisă a dependențelor este mai clară decât accesul global — singleton-ul este ultima soluție, nu prima.
Avantaje și dezavantaje
Avantaje: instanță unică garantată; constructorul privat face imposibilă crearea unei a doua; crearea este leneșă, deci nu se construiește nimic până când cineva nu cere.
Dezavantaje: este o variabilă globală deghizată — dependențele ascunse fac codul mai greu de urmărit; testele nu îl pot înlocui ușor cu unul fals, iar un test poate lăsa stare în urmă pentru următorul; folosirea în exces duce la programe încâlcite.