S
Singleton Pattern
The Singleton pattern ensures a class has only one instance throughout the application.
Code
typescript
1// Database connection singleton2class Database {3 private static instance: Database | null = null;4 private connected: boolean = false;5 6 // Private constructor prevents direct instantiation7 private constructor(private connectionString: string) {}8 9 // Static method to get the single instance10 static getInstance(connectionString?: string): Database {11 if (!Database.instance) {12 if (!connectionString) {13 throw new Error("Connection string required for first initialization");14 }15 Database.instance = new Database(connectionString);16 }17 return Database.instance;18 }19 20 async connect(): Promise<void> {21 if (this.connected) {22 console.log("Already connected");23 return;24 }25 26 console.log(`Connecting to ${this.connectionString}...`);27 // Simulated connection28 await new Promise((resolve) => setTimeout(resolve, 100));29 this.connected = true;30 console.log("Connected!");31 }32 33 async query(sql: string): Promise<unknown[]> {34 if (!this.connected) {35 throw new Error("Not connected to database");36 }37 console.log(`Executing: ${sql}`);38 return []; // Simulated result39 }40 41 async disconnect(): Promise<void> {42 if (!this.connected) return;43 console.log("Disconnecting...");44 this.connected = false;45 }46 47 // For testing - reset the singleton48 static resetInstance(): void {49 Database.instance = null;50 }51}52 53// Configuration singleton using a class54class Config {55 private static instance: Config;56 private settings: Map<string, unknown> = new Map();57 58 private constructor() {59 // Load default settings60 this.settings.set("apiUrl", "https://api.example.com");61 this.settings.set("timeout", 5000);62 this.settings.set("debug", false);63 }64 65 static getInstance(): Config {66 if (!Config.instance) {67 Config.instance = new Config();68 }69 return Config.instance;70 }71 72 get<T>(key: string): T | undefined {73 return this.settings.get(key) as T | undefined;74 }75 76 set<T>(key: string, value: T): void {77 this.settings.set(key, value);78 }79}80 81// Usage example82async function main(): Promise<void> {83 // Database singleton84 const db1 = Database.getInstance("postgres://localhost:5432/mydb");85 const db2 = Database.getInstance(); // Returns same instance86 87 console.log("Same instance?", db1 === db2); // true88 89 await db1.connect();90 await db1.query("SELECT * FROM users");91 92 // Config singleton93 const config = Config.getInstance();94 console.log("API URL:", config.get<string>("apiUrl"));95 96 config.set("debug", true);97 console.log("Debug mode:", config.get<boolean>("debug"));98}99 100main().catch(console.error);Run this example locally
$ npx ts-node patterns/singleton.ts