उदाहरणों के साथ JavaScript में डिज़ाइन पैटर्न: A से Z तक
\n\nडिज़ाइन पैटर्न (design patterns) सॉफ्टवेयर विकास के दौरान उत्पन्न होने वाली सामान्य समस्याओं के सिद्ध समाधान हैं। JavaScript में, विशेष रूप से Node.js वातावरण में, इन टेम्पलेट्स को समझना अधिक स्वच्छ, मॉड्यूलर और स्केलेबल कोड लिखने में मदद करता है। इस लेख में, हम स्पष्ट उदाहरणों के साथ पैटर्न की मुख्य श्रेणियों पर चर्चा करेंगे।
\n\n1. क्रिएशनल पैटर्न (Creational Patterns)
\nये पैटर्न ऑब्जेक्ट निर्माण की प्रक्रिया को प्रबंधित करते हैं, सिस्टम को उनके इंस्टेंशिएशन के तरीके से स्वतंत्र बनाते हैं।
\n\n1.1. सिंगलटन (Singleton)
\nयह सुनिश्चित करता है कि क्लास का केवल एक इंस्टेंस हो, और उस तक वैश्विक पहुँच प्रदान करता है। Node.js में, मॉड्यूल डिफ़ॉल्ट रूप से कैश होते हैं, जो कार्यान्वयन को सरल बनाता है।
\nclass DatabaseConnection {\n constructor() {\n if (DatabaseConnection.instance) {\n return DatabaseConnection.instance;\n }\n this.connection = null;\n DatabaseConnection.instance = this;\n }\n\n connect() {\n if (!this.connection) {\n this.connection = { status: 'connected' };\n console.log('नया DB कनेक्शन');\n }\n return this.connection;\n }\n}\n\nconst db1 = new DatabaseConnection();\nconst db2 = new DatabaseConnection();\nconsole.log(db1 === db2); // true\n\n1.2. फ़ैक्टरी मेथड (Factory Method)
\nऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस परिभाषित करता है, लेकिन उपवर्गों को बनाए जाने वाले ऑब्जेक्ट के प्रकार को बदलने की अनुमति देता है। विभिन्न प्रकार के लॉगर बनाने के लिए आदर्श।
\nclass LoggerFactory {\n createLogger(type) {\n switch (type) {\n case 'console':\n return new ConsoleLogger();\n case 'file':\n return new FileLogger();\n default:\n throw new Error('अज्ञात लॉगर प्रकार');\n }\n }\n}\n\nclass ConsoleLogger {\n log(message) { console.log(message); }\n}\n\nclass FileLogger {\n log(message) { console.log(`[फ़ाइल]: ${message}`); }\n}\n\nconst factory = new LoggerFactory();\nconst logger = factory.createLogger('console');\nlogger.log('परीक्षण संदेश');\n\n2. स्ट्रक्चरल पैटर्न (Structural Patterns)
\nये बड़ी संरचनाएँ बनाने के लिए क्लासेस और ऑब्जेक्ट्स को संयोजित करने के तरीकों का वर्णन करते हैं।
\n\n2.1. डेकोरेटर (Decorator)
\nगतिशील रूप से किसी ऑब्जेक्ट में नई जिम्मेदारियाँ जोड़ता है। JavaScript में, डेकोरेटर अक्सर हायर-ऑर्डर फ़ंक्शन या प्रोटोटाइप के माध्यम से कार्यान्वित किए जाते हैं।
\nclass Coffee {\n cost() { return 10; }\n description() { return 'कॉफ़ी'; }\n}\n\nfunction withMilk(coffee) {\n coffee.cost = () => coffee.cost() + 5;\n coffee.description = () => coffee.description() + ', दूध के साथ';\n return coffee;\n}\n\nfunction withSugar(coffee) {\n coffee.cost = () => coffee.cost() + 2;\n coffee.description = () => coffee.description() + ', चीनी के साथ';\n return coffee;\n}\n\nlet myCoffee = new Coffee();\nmyCoffee = withMilk(myCoffee);\nmyCoffee = withSugar(myCoffee);\nconsole.log(`${myCoffee.description()}: ${myCoffee.cost()} रुपये`); // कॉफ़ी, दूध के साथ, चीनी के साथ: 17 रुपये\n\n2.2. एडेप्टर (Adapter)
\nएक क्लास के इंटरफ़ेस को दूसरे इंटरफ़ेस में बदलता है जिसकी क्लाइंट को अपेक्षा होती है। तृतीय-पक्ष लाइब्रेरीज़ को एकीकृत करते समय विशेष रूप से उपयोगी।
\nclass OldAPI {\n getUserData() {\n return { name: 'इवान', age: 25, email: 'ivan@example.com' };\n }\n}\n\nclass NewAPI {\n fetchUser() {\n return { fullName: 'इवान पेत्रोव', yearsOld: 26, contact: 'ivan@example.com' };\n }\n}\n\nclass UserAdapter {\n constructor(api) {\n this.api = api;\n }\n\n getUserData() {\n const data = this.api.fetchUser();\n return {\n name: data.fullName,\n age: data.yearsOld,\n email: data.contact\n };\n }\n}\n\nconst adapter = new UserAdapter(new NewAPI());\nconsole.log(adapter.getUserData()); // { name: 'इवान पेत्रोव', age: 26, email: 'ivan@example.com' }\n\n3. बिहेवियरल पैटर्न (Behavioral Patterns)
\nये एल्गोरिदम को परिभाषित करते हैं