Go में डिपेंडेंसी इंजेक्शन: शुरुआती लोगों के लिए
\n\nडिपेंडेंसी इंजेक्शन (DI), या निर्भरता इंजेक्शन, एक प्रमुख डिज़ाइन पैटर्न है जो स्वच्छ, परीक्षण योग्य और रखरखाव योग्य कोड लिखने में मदद करता है। Go की दुनिया में, जहाँ सादगी और स्पष्टता को सबसे अधिक महत्व दिया जाता है, DI 'दैवीय ऑब्जेक्ट' बनाने और घटकों के बीच कठोर संबंधों से बचने में मदद करता है। इस लेख में, हम समझेंगे कि Go में डिपेंडेंसी इंजेक्शन क्या है, इसकी आवश्यकता क्यों है, और सरल और समझने योग्य उदाहरणों का उपयोग करके इसे व्यवहार में कैसे लागू किया जाए।
\n\nडिपेंडेंसी इंजेक्शन क्या है?
\n\nकल्पना करें कि आप एक प्रोग्राम लिख रहे हैं जो उपयोगकर्ताओं को स्वागत ईमेल भेजता है। आपका कोड संभवतः इस तरह दिखेगा:
\n\npackage main\n\nimport "fmt"\n\ntype EmailService struct{}\n\nfunc (e *EmailService) SendWelcomeEmail(userEmail string) {\n fmt.Printf("%s को ईमेल भेजा जा रहा है\\n", userEmail)\n}\n\ntype UserController struct {\n emailService *EmailService\n}\n\nfunc NewUserController() *UserController {\n return &UserController{\n emailService: &EmailService{}, // कठोर संबंध\n }\n}\n\nfunc (uc *UserController) RegisterUser(email string) {\n // ... रजिस्ट्रेशन लॉजिक\n uc.emailService.SendWelcomeEmail(email)\n}\n\nfunc main() {\n controller := NewUserController()\n controller.RegisterUser("user@example.com")\n}\n\nइस कोड की समस्या यह है कि UserController स्वयं EmailService का एक इंस्टेंस बनाता है। इसे कठोर संबंध कहा जाता है। यदि आप EmailService को, मान लीजिए, SmsService से बदलना चाहते हैं या परीक्षण के लिए मॉक ऑब्जेक्ट का उपयोग करना चाहते हैं, तो आपको UserController के अंदर कोड बदलना होगा।
डिपेंडेंसी इंजेक्शन इस समस्या का समाधान करता है। स्ट्रक्चर के अंदर निर्भरताएँ बनाने के बजाय, हम उन्हें बाहर से 'इंजेक्ट' करते हैं। मुख्य विचार है: "यह मत पूछो कि तुम्हें क्या चाहिए। बताओ कि तुम्हें क्या चाहिए, और इसे तैयार प्राप्त करो।"
\n\nकंस्ट्रक्टर के माध्यम से मैन्युअल डिपेंडेंसी इंजेक्शन
\n\nGo में DI का सबसे सरल और सामान्य तरीका कंस्ट्रक्टर फ़ंक्शन के माध्यम से निर्भरताएँ पास करना है। आइए अपने उदाहरण को फिर से लिखें:
\n\npackage main\n\nimport "fmt"\n\n// लचीलेपन के लिए इंटरफ़ेस परिभाषित करें\ntype Notifier interface {\n Send(to string, message string) error\n}\n\ntype EmailService struct{}\n\nfunc (e *EmailService) Send(to string, message string) error {\n fmt.Printf("%s को ईमेल: %s\\n", to, message)\n return nil\n}\n\ntype SmsService struct{}\n\nfunc (s *SmsService) Send(to string, message string) error {\n fmt.Printf("%s को SMS: %s\\n", to, message)\n return nil\n}\n\ntype UserController struct {\n notifier Notifier // इंटरफ़ेस के माध्यम से निर्भरता\n}\n\n// NewUserController — कंस्ट्रक्टर जो निर्भरता स्वीकार करता है\nfunc NewUserController(n Notifier) *UserController {\n return &UserController{\n notifier: n,\n }\n}\n\nfunc (uc *UserController) RegisterUser(email string) {\n // ... बिज़नेस लॉजिक\n uc.notifier.Send(email, "स्वागत है!")\n}\n\nfunc main() {\n // मैन्युअल रूप से निर्भरता इंजेक्ट करें\n emailNotifier := &EmailService{}\n controller := NewUserController(emailNotifier)\n controller.RegisterUser("user@example.com")\n\n // आसानी से कार्यान्वयन बदलें\n smsNotifier := &SmsService{}\n controller2 := NewUserController(smsNotifier)\n controller2.RegisterUser("+123456789")\n}\n\nक्या बदला?
\n- \n
- हमने एक इंटरफ़ेस
Notifierपरिभाषित किया। अबUserControllerको यह नहीं पता कि कौन सी सेवा उपयोग हो रही है — ईमेल या SMS। \n - कंस्ट्रक्टर
NewUserControllerएक आर्गुमेंट के रूप मेंNotifierस्वीकार करता है। यही डिपेंडेंसी इंजेक्शन है। \n mainमें, हम स्वयं तय करते हैं कि कौन सा कार्यान्वयन पास करना है। \n
यह दृष्टिकोण कोड को लचीला, परीक्षण योग्य और इन्वर्ज़न ऑफ़ कंट्रोल सिद्धांत के अनुरूप बनाता है।