कल अपने लेख में, मैंने "डिपेंडेंसी ट्रेन" की अवधारणा पेश की। ऐसा तब होता है जब आप अपनी कोड लाइब्रेरी से कोई फ़ंक्शन आयात करते हैं, लेकिन अंत में आपको सभी निर्भरताओं को पूरा करने के लिए कई अतिरिक्त मॉड्यूल आयात करने पड़ते हैं। जब आपको केवल एक "सीट" (फ़ंक्शन) की आवश्यकता होती है, तो आपके पास कोड मॉड्यूल की एक पूरी "ट्रेन" बची होती है।
आप इस स्थिति में समाप्त होते हैं जब आप मॉड्यूल कसकर युग्मित होते हैं। तो आप इसके बारे में क्या कर सकते हैं? इस स्थिति से निपटने के कुछ तरीके हैं।
उल्लंघन करें "अपने आप को न दोहराएं"
ढीले युग्मन को संरक्षित करने का एक तरीका - जिसके परिणामस्वरूप अधिक "स्टैंडअलोन" मॉड्यूल होते हैं - कॉलिंग मॉड्यूल में स्रोत मॉड्यूल से कार्यों की निजी प्रतियां बनाना है। यह दो मॉड्यूल के बीच निर्भरता को समाप्त करता है, लेकिन इसका परिणाम दोहराव वाले कोड में होता है।
अवधारणा सरल है। आप फ़ंक्शन को उसके प्राथमिक कोड मॉड्यूल से कॉपी करते हैं। फिर आप इसे कॉलिंग मॉड्यूल में पेस्ट करें लेकिन अस्पष्टता से बचने के लिए इसे निजी के रूप में चिह्नित करें।
यह निम्नलिखित स्थितियों में समझ में आता है:
- बिना जटिल तर्क वाली सरल विधियाँ।
- प्रक्रियाएं जिनके बदलने की संभावना नहीं है।
- जब दिनचर्या बहुत बड़े मॉड्यूल का हिस्सा हो और आपको मॉड्यूल में किसी अन्य फ़ंक्शन की आवश्यकता न हो। एक फ़ंक्शन को कॉपी करने से ब्लोट से बचा जा सकता है।
इस दृष्टिकोण में निम्नलिखित कमियां हैं:
- अगर वहाँ है कॉपी किए गए फ़ंक्शन में एक बग, आपको इसे कई जगहों पर ठीक करना होगा।
- यदि आप फिर भी स्रोत मॉड्यूल का आयात करते हैं तो आपके पास कोड दोहराव है।
अपनी लड़ाई चुनें
मैं अपने सभी मानक कोड लाइब्रेरी मॉड्यूल को पूरी तरह से स्टैंडअलोन रखने के लिए बहुत अधिक समय तक जाता था। समस्या यह थी कि इसके परिणामस्वरूप बहुत सारे कोड दोहराव हुए। इसका कारण यह है कि निजी उपयोग के लिए मैं जिन कार्यों को अन्य मॉड्यूल में कॉपी कर रहा था उनमें से अधिकांश मॉड्यूल से आए थे जिन्हें मैं अपने आवेदन में आयात कर रहा था।
इसका एक प्रमुख उदाहरण मेरा StringFunctions था मापांक। उस मॉड्यूल में कई सरल तरीके हैं जो मेरे कोड को और अधिक पठनीय बनाने के लिए बड़े पैमाने पर मौजूद हैं। उदाहरण के लिए, मेरे पास Conc()
है फ़ंक्शन जिसे मैं अपने आधे से अधिक कोड लाइब्रेरी मॉड्यूल में एक निजी फ़ंक्शन के रूप में शामिल कर रहा था।
समय के साथ मुझे एहसास हुआ कि मैंने उस StringFunctions . को शामिल किया है मेरी सभी परियोजनाओं में मॉड्यूल। जब मैंने उस मॉड्यूल से एक फ़ंक्शन को कॉल किया, तो मैं कभी भी एक नई निर्भरता का परिचय नहीं दे रहा था। मैं समय बर्बाद कर रहा था और बहुत कम या बिना किसी लाभ के डुप्लिकेट कोड पेश कर रहा था।
कुछ कोड मॉड्यूल थे जिन्हें मैं सुरक्षित रूप से मान सकता था कि प्रत्येक एप्लिकेशन में होगा। वे फ़ंक्शन वाले मॉड्यूल थे जिनका मैं अक्सर उपयोग करता था। जिसका मतलब था कि इनमें से कई निर्भरताओं को अनिवार्य रूप से अनदेखा किया जा सकता है।
अब मैं कोड मॉड्यूल की "मानक लाइब्रेरी" बनाए रखता हूं जिसे मैं शुरुआत में ही हर नई परियोजना में आयात करता हूं। मैं स्वतंत्र रूप से उन मॉड्यूल से फ़ंक्शन को कॉल करता हूं जो अब इस ज्ञान में सुरक्षित हैं कि मैं नई निर्भरता का परिचय नहीं दूंगा।
एक अद्वितीय टिप्पणी टोकन का उपयोग करें
मेरी "स्टैंडर्ड लाइब्रेरी" के मॉड्यूल में से एक क्लास मॉड्यूल है (clsApp ) जिसमें एप्लिकेशन-स्तरीय गुण और विधियां शामिल हैं, जैसे वर्तमान उपयोगकर्ता नाम और शीर्षक बार टेक्स्ट। मैं clsApp . के भीतर से अन्य वर्ग मॉड्यूल को भी उजागर करता हूं , जैसे clsStatus और clsRegistry , जो क्रमशः एक्सेस स्टेटस बार और विंडोज रजिस्ट्री को अधिक पठनीय एक्सेस प्रदान करते हैं।
हालांकि, मुझे प्रत्येक प्रोजेक्ट में स्टेटस बार या विंडोज रजिस्ट्री तक पहुंच की आवश्यकता नहीं है। इसलिए, clsStatus . पर निर्भरता बनाने से बचने के लिए या clsRegistry कक्षाएं, मैं एक अद्वितीय "टिप्पणी टोकन" का उपयोग करके उन वर्गों को संदर्भित करने वाले कोड पर टिप्पणी करूंगा।
उदाहरण के साथ प्रदर्शित करना सबसे आसान है:
' Notes
' - Find and replace '$$ with blank to enable Status property (requires clsStatus)
' - Find and replace '&& with blank to enable Reg property (requires clsRegistry)
'$$Private m_objStatus As clsStatus
'&&Private m_objReg As clsRegistry
'$$Public Property Get Status() As clsStatus
'$$ Set Status = m_objStatus
'$$End Property
'&&Public Property Get Reg() As clsRegistry
'&& Set Reg = m_objReg
'&&End Property
Private Sub Class_Initialize()
'$$ Set m_objStatus = New clsStatus
'&& Set m_objReg = New clsRegistry
End Sub
अगर मैं Status
को सक्षम करना चाहता हूं उपरोक्त वर्ग की संपत्ति, मैं एक वैश्विक खोज कर सकता हूं और '$$
. पर प्रतिस्थापित कर सकता हूं .
इसने कुछ समय के लिए ठीक काम किया, लेकिन यह मुझे हमेशा अटपटा लगा। शायद इसलिए कि था। ध्यान देने वाली दूसरी बात यह है कि मेरे पूरे कोड पुस्तकालय में टिप्पणी टोकन को विश्व स्तर पर अद्वितीय होना चाहिए। अगर मैं इस दृष्टिकोण के साथ लंबे समय तक अटका रहता तो यह एक रखरखाव दुःस्वप्न होता।
सशर्त संकलन का उपयोग करें
सशर्त संकलन का लाभ उठाने के लिए एक बहुत साफ दृष्टिकोण है। वीबीए में वे रेखाएं हैं जो पाउंड/हैशटैग चिह्न ("#") से शुरू होती हैं। उस वर्ण से शुरू होने वाली पंक्तियाँ "प्रीप्रोसेसिंग" के अधीन होती हैं।
प्रीप्रोसेसिंग क्या है? यह एक ऐसा कदम है जो प्रोग्रामिंग भाषाएं संकलन से पहले उठाती हैं। इसलिए, किसी भी संकलन समय की जाँच होने से पहले, प्रीप्रोसेसिंग लाइनों का मूल्यांकन किया जाता है। यह हमें कोड रखने की अनुमति देता है जो अन्यथा हमारी परियोजनाओं में संकलित करने में विफल रहेगा।
हम अपने कोड पुस्तकालयों के साथ इसका लाभ कैसे उठा सकते हैं? फिर से, उदाहरण के साथ प्रदर्शित करना सबसे आसान है:
' Notes
' - Replace the '$$ and '&& kludges with conditional compilation
#Const EnableStatusProperty = True 'If True, requires import of clsStatus class
#Const EnableRegProperty = False 'If True, requires import of clsRegistry class
#If EnableStatusProperty Then
Private m_objStatus As clsStatus
#End If
#If EnableRegProperty Then
Private m_objReg As clsRegistry
#End If
#If EnableStatusProperty Then
Public Property Get Status() As clsStatus
Set Status = m_objStatus
End Property
#End If
#If EnableRegProperty Then
Public Property Get Reg() As clsRegistry
Set Reg = m_objReg
End Property
#End If
Private Sub Class_Initialize()
#If EnableStatusProperty Then
Set m_objStatus = New clsStatus
#End If
#If EnableRegProperty Then
Set m_objReg = New clsRegistry
#End If
End Sub
दोनों दुनिया के सर्वश्रेष्ठ
जैसा कि आप देख सकते हैं, यह "डिपेंडेंसी ट्रेन" समस्या से बचने का एक बहुत ही साफ तरीका है।
यह हमें वैकल्पिक निर्भरता बनाने की अनुमति देता है . कोड का हर टुकड़ा जो किसी अन्य कोड लाइब्रेरी मॉड्यूल पर निर्भर करता है, एक सशर्त संकलन के अंदर लपेटा जाता है # यदि ... फिर कथन। सशर्त संकलन स्थिरांक सभी कोड मॉड्यूल के शीर्ष पर सूचीबद्ध हैं।
अब जब हम अपने कोड लाइब्रेरी मॉड्यूल के एक अपडेटेड वर्जन को फिर से इम्पोर्ट करते हैं, तो हमें बस कंडीशनल कंपाइलेशन फ्लैग को पूरा करना होता है और पहले की तुलना में बहुत कुछ सेट करना होता है। अगर हमें याद नहीं है कि झंडे कैसे सेट किए गए थे, तो हमें प्रोजेक्ट पूरी तरह से संकलित होने तक झंडे को संकलित और समायोजित करने में सक्षम होना चाहिए।
और अगर हम संस्करण नियंत्रण का उपयोग कर रहे हैं, तो हमें यह भूलने की चिंता नहीं है कि पहले क्या था।