TypeScript में Singleton पैटर्न: शुरुआत से विशेषज्ञता तक

मूल बातें 🌟

Singleton पैटर्न का परिचय

कल्पना कीजिए एक ऐसे सुपरहीरो की, जो पूरे ब्रह्मांड में केवल एक बार मौजूद हो सकता है। यही है Singleton पैटर्न! 🦸‍♂️

एक अनूठे हीरो की जरूरत क्यों? 🤔

कुछ आम परिस्थितियां:

  • 🎮 एक वीडियो गेम में कई स्कोरबोर्ड... पूरी अव्यवस्था!
  • 🏦 एक ही डेटाबेस के कई कनेक्शन... संसाधनों की बर्बादी!
  • ⚙️ कई अलग-अलग कॉन्फ़िगरेशन... अराजकता का द्वार!

Singleton की सुपरपावर्स

  • 💪 एकता की शक्ति: एक ही इंस्टेंस, जैसे गोथम सिटी का एक ही बैटमैन
  • 🌟 वैश्विक दृष्टि: हर जगह से पहुंच, जैसे आसमान में बैट-सिग्नल
  • 🎯 सटीकता: सत्य का एक ही स्रोत, जैसे सॉरन की एक ही अंगूठी

बेसिक इम्प्लीमेंटेशन

हमारे हीरो का कोड

typescript
1class Logger {
2 private static instance: Logger;
3 private logCount: number = 0;
4
5 private constructor() {
6 console.log('🚀 Logger जाग रहा है...');
7 }
8
9 public static getInstance(): Logger {
10 if (!Logger.instance) {
11 Logger.instance = new Logger();
12 }
13 return Logger.instance;
14 }
15
16 public log(message: string): void {
17 this.logCount++;
18 console.log(`📝 [लॉग #${this.logCount}] ${message}`);
19 }
20
21 public getStats(): string {
22 return `📊 कुल लॉग: ${this.logCount}`;
23 }
24}

सरल उपयोग

typescript
1const logger = Logger.getInstance();
2logger.log('हमारा हीरो तैयार है!');
3console.log(logger.getStats());

उन्नत तकनीकें 🚀

थ्रेड-सेफ Singleton

मल्टी-थ्रेड वातावरण में, हमारे हीरो को अतिरिक्त कवच की जरूरत है! यहाँ एक थ्रेड-सेफ कार्यान्वयन है:

typescript
1class ThreadSafeLogger {
2 private static instance: ThreadSafeLogger;
3 private static instanceLock = false;
4 private logs: string[] = [];
5
6 private constructor() {}
7
8 public static getInstance(): ThreadSafeLogger {
9 if (!ThreadSafeLogger.instanceLock) {
10 ThreadSafeLogger.instanceLock = true;
11 if (!ThreadSafeLogger.instance) {
12 ThreadSafeLogger.instance = new ThreadSafeLogger();
13 }
14 ThreadSafeLogger.instanceLock = false;
15 }
16 return ThreadSafeLogger.instance;
17 }
18}

लेजी इनिशियलाइजेशन वाला Singleton 🦥

typescript
1class LazyLogger {
2 private static instance: LazyLogger;
3 private config: object;
4
5 private constructor(config: object) {
6 this.config = config;
7 }
8
9 public static getInstance(config?: object): LazyLogger {
10 if (!LazyLogger.instance && config) {
11 LazyLogger.instance = new LazyLogger(config);
12 }
13 if (!LazyLogger.instance) {
14 throw new Error(
15 'पहली बार इनिशियलाइज करते समय Logger को कॉन्फ़िगरेशन की आवश्यकता है!',
16 );
17 }
18 return LazyLogger.instance;
19 }
20}

टेस्टिंग के लिए रीसेट करने योग्य Singleton 🧪

typescript
1class TestableLogger {
2 private static instance: TestableLogger;
3
4 private constructor() {}
5
6 public static getInstance(): TestableLogger {
7 if (!TestableLogger.instance) {
8 TestableLogger.instance = new TestableLogger();
9 }
10 return TestableLogger.instance;
11 }
12
13 // टेस्टिंग के लिए विशेष मेथड
14 public static resetInstance(): void {
15 TestableLogger.instance = null;
16 }
17}

जेनेरिक Singleton 🎭

typescript
1class GenericSingleton<T> {
2 private static instances: Map<string, any> = new Map();
3
4 protected constructor() {}
5
6 public static getInstance<T>(this: new () => T): T {
7 const className = this.name;
8 if (!GenericSingleton.instances.has(className)) {
9 GenericSingleton.instances.set(className, new this());
10 }
11 return GenericSingleton.instances.get(className);
12 }
13}
14
15// उपयोग
16class UserService extends GenericSingleton<UserService> {
17 public getUsers() {
18 return ['user1', 'user2'];
19 }
20}
21
22class ConfigService extends GenericSingleton<ConfigService> {
23 public getConfig() {
24 return { api: 'url' };
25 }
26}

एंटी-पैटर्न और बचने योग्य जाल ⚠️

  1. टाइट कपलिंग
typescript
1// बचें ❌
2class BadSingleton {
3 public static getInstance() {
4 // कोड...
5 }
6 public doDirectDatabaseOperation() {
7 // डेटाबेस पर सीधा ऑपरेशन
8 }
9}
10
11// बेहतर विकल्प ✅
12interface DatabaseOperation {
13 execute(): void;
14}
15
16class GoodSingleton {
17 public static getInstance() {
18 // कोड...
19 }
20 public executeOperation(operation: DatabaseOperation) {
21 operation.execute();
22 }
23}
  1. ग्लोबल म्यूटेबल स्टेट
typescript
1// बचें ❌
2class MutableSingleton {
3 private static instance: MutableSingleton;
4 public globalState: any = {};
5}
6
7// बेहतर विकल्प ✅
8class ImmutableSingleton {
9 private static instance: ImmutableSingleton;
10 private state: Readonly<any>;
11
12 public getState(): Readonly<any> {
13 return this.state;
14 }
15}

पूरक पैटर्न्स 🤝

फैक्टरी + Singleton

typescript
1interface Logger {
2 log(message: string): void;
3}
4
5class LoggerFactory {
6 private static instance: LoggerFactory;
7 private loggers: Map<string, Logger> = new Map();
8
9 private constructor() {}
10
11 public static getInstance(): LoggerFactory {
12 if (!LoggerFactory.instance) {
13 LoggerFactory.instance = new LoggerFactory();
14 }
15 return LoggerFactory.instance;
16 }
17
18 public getLogger(type: 'console' | 'file'): Logger {
19 if (!this.loggers.has(type)) {
20 this.loggers.set(type, this.createLogger(type));
21 }
22 return this.loggers.get(type);
23 }
24
25 private createLogger(type: 'console' | 'file'): Logger {
26 // विशिष्ट logger का निर्माण
27 return type === 'console' ? new ConsoleLogger() : new FileLogger();
28 }
29}

उन्नत चुनौती 🎯

एक ऐसा Singleton बनाएं जो:

  1. थ्रेड-सेफ हो
  2. लेजी इनिशियलाइजेशन का उपयोग करे
  3. टेस्टिंग के लिए रीसेट की अनुमति दे
  4. वर्जनिंग सिस्टम को एकीकृत करे
typescript
1// अपना कोड यहाँ लिखें!

अंतिम शब्द 🎬

Singleton एक शक्तिशाली पैटर्न है, लेकिन इसके कार्यान्वयन में सोच-समझ की जरूरत है। सरल मामलों के लिए बेसिक वर्जन पर्याप्त है, लेकिन जटिल एप्लिकेशन के लिए उन्नत वर्जन अधिक मजबूती और लचीलापन प्रदान करते हैं।

प्रो टिप्स 💡

  • महंगे संसाधनों के लिए लेजी इनिशियलाइजेशन का उपयोग करें
  • हमेशा टेस्टेबिलिटी के बारे में सोचें
  • जहां संभव हो डिपेंडेंसी इंजेक्शन को प्राथमिकता दें
  • अपने Singleton के उपयोग के मामलों को अच्छी तरह से डॉक्यूमेंट करें

प्रैक्टिकल अभ्यास 🎮

  1. एप्लिकेशन कॉन्फ़िगरेशन प्रबंधन के लिए एक Singleton बनाएं
  2. मैसेज क्यू के साथ एक थ्रेड-सेफ Singleton बनाएं
  3. Singleton पैटर्न का उपयोग करते हुए एक कैशिंग सिस्टम विकसित करें

हैप्पी कोडिंग! 🚀

इस लेख को साझा करें


Sébastien Timoner

Sébastien TIMONER

लीड डेवलपर
कस्टम डेवलपमेंट विशेषज्ञ
Aix-en-Provence, France

वेब विकास और तकनीकी टीम प्रबंधन में विशेषज्ञ, मैं प्रभावी डिजिटल समाधानों के निर्माण और अनुकूलन में विशेषज्ञता रखता हूं। React.js, Node.js, TypeScript और Symfony जैसी आधुनिक तकनीकों की गहरी समझ के साथ, मैं offroadLabs में विभिन्न क्षेत्रों की कंपनियों के लिए जटिल SaaS परियोजनाओं की सफलता सुनिश्चित करता हूं, डिजाइन से लेकर प्रोडक्शन तक।

offroadLabs में, मैं तकनीकी विशेषज्ञता और सहयोगात्मक दृष्टिकोण को जोड़ते हुए कस्टम विकास सेवाएं प्रदान करता हूं। चाहे एक नवीन SaaS समाधान बनाना हो, मौजूदा एप्लिकेशन को आधुनिक बनाना हो, या एक टीम के कौशल विकास में सहायता करना हो, मैं प्रत्येक परियोजना की विशिष्ट आवश्यकताओं के अनुरूप मजबूत और प्रभावी समाधान प्रदान करने के लिए प्रतिबद्ध हूं।

मैं ऐक्स-एन-प्रोवेंस के आसपास या पूर्ण रिमोट असाइनमेंट के लिए उपलब्ध हूं।