आपके रेल्स करियर में किसी बिंदु पर, आप एक ऐसे कंट्रोलर में फंसेंगे जो आपको हमेशा के लिए प्रोग्रामिंग छोड़ने पर मजबूर कर देगा। इसमें पूरी फीचर के लिए कोड की हर लाइन हो सकती है। इसमें 15 before_filters हो सकते हैं जो सभी इंस्टेंस वेरिएबल के माध्यम से संवाद करते हैं और जिन्हें एक विशिष्ट क्रम में कॉल किया जाना चाहिए या चीजें फट जाएंगी। और, अनिवार्य रूप से, इसके टेस्ट इस तरह दिखेंगे:
test "index" do get :index assert_response :success end बहुत बढ़िया। 100% टेस्ट कवरेज, है ना?
जितना अच्छा यह होगा कि बस अपनी आँखें बंद करें और दिखावा करें कि यह मौजूद नहीं है, किसी दिन आपको इन कंट्रोलर्स में से एक में बग ठीक करना होगा। और, एक अच्छे सॉफ्टवेयर डेवलपर होने के नाते, आप कोड को उससे बेहतर छोड़ना चाहते हैं जैसा आपने पाया था।
लेकिन आप कैसे रिफैक्टर कर सकते हैं, खासकर भरोसा करने के लिए अच्छे टेस्ट के बिना?
किसी तरह इसे टेस्ट करें
रिफैक्टरिंग करते समय सुरक्षित महसूस करने के लिए आपको अच्छे टेस्ट की आवश्यकता होती है, लेकिन आप इस कोड के खिलाफ अच्छे टेस्ट नहीं लिख सकते जब तक आप रिफैक्टर नहीं करते। तो आप क्या कर सकते हैं?
खैर, चाहे आपका कंट्रोलर कितना भी बुरी तरह लिखा गया हो, आप अभी भी इंटीग्रेशन टेस्ट लिख सकते हैं जो कंट्रोलर को कुछ डेटा भेजते हैं और उससे कुछ प्रतिक्रिया की उम्मीद करते हैं। अभी के लिए, आपको ऐसे टेस्ट लिखने चाहिए जो यह सुनिश्चित करें कि कंट्रोलर का मौजूदा व्यवहार नहीं बदलता जब आप रिफैक्टर करते हैं।
ये टेस्ट यूनिट टेस्ट जितने केंद्रित नहीं होंगे। लेकिन ये उच्च-स्तरीय टेस्ट आपको यह महसूस करने में सहज बना सकते हैं कि आप जो रिफैक्टरिंग करने वाले हैं वह सब कुछ नहीं तोड़ देगा। और उन्हें लिखने की प्रक्रिया आपको अपने कोड को बेहतर ढंग से समझने में मदद करेगी, जो आपको यह तय करने में मदद करेगी कि इसे कैसे रिफैक्टर करना है।
अपनी निर्भरताएं तोड़ें
खराब कंट्रोलर कोड को खराब क्या बनाता है? ज्यादातर समय, यह before_filters, हेल्पर मेथड, या 200-लाइन फंक्शन के विभिन्न हिस्सों के बीच निहित निर्भरताएं हैं। यह बहुत जल्दी रिफैक्टरिंग का मामला भी हो सकता है। कोड को बेहतर बनाने के लिए, आपको इन निर्भरताओं को तोड़ने की आवश्यकता है।
रेल्स कंट्रोलर के लिए, निर्भरताओं को तोड़ने का एक आसान तरीका है। बस अपने before_filters, हेल्पर मेथड, सुपरक्लास, और कहीं और जहां कंट्रोलर जैसा कोड छिपा हो सकता है, से कोड कॉपी करें। फिर, उन मेथड को कॉल को आपके द्वारा कॉपी किए गए कोड से बदलें।
आप अस्थायी रूप से अपने कोड को अन-DRY कर रहे हैं, ताकि आप इसे बाद में अधिक समझने योग्य तरीके से रिफैक्टर कर सकें। यह बदसूरत है, लेकिन अब आपका सारा कोड खुले में है। आपको यह देखने में सक्षम होना चाहिए कि कौन से टुकड़े इंटरैक्ट करते हैं और सब कुछ कैसे प्रवाहित होता है।
(इस प्रक्रिया के दौरान, आपको हर बदलाव के बाद अपने टेस्ट चलाते रहना चाहिए ताकि यह सुनिश्चित हो सके कि आपका इनलाइनिंग कुछ भी नहीं तोड़ रहा है।)
टेस्टेबल कोड की ओर रिफैक्टर करें
अब, आप अपने कोड को फिर से रिफैक्टर करने के लिए तैयार हैं। आप शायद बुनियादी एक्सट्रैक्ट मेथड, एक्सट्रैक्ट ऑब्जेक्ट, पुल अप मेथड-टाइप रिफैक्टरिंग पर टिके रहेंगे। अपने कोड को कुछ अलग तरीकों से रिफैक्टर करने की कोशिश करें और देखें कि क्या सबसे अच्छा लगता है।
पहले कुछ पास के दौरान, आप अपने उच्च-स्तरीय इंटीग्रेशन टेस्ट पर सुरक्षा जाल के रूप में भरोसा कर सकते हैं। लेकिन जल्द ही, आप कुछ बेहतर चाहेंगे।
जैसे-जैसे आप रिफैक्टर करते हैं, अपने कोड को अधिक टेस्टेबल बनाने के अवसरों की तलाश करें। इसका आमतौर पर मतलब होगा टेस्ट डबल्स इंजेक्ट करने के लिए स्थान बनाना, अपने ऑब्जेक्ट्स के बीच निर्भरताओं को कम करना, और अपने कंट्रोलर को उन ऑब्जेक्ट्स पर भरोसा करने के लिए बनाना जिन्हें आसानी से बनाया और यूनिट टेस्ट किया जा सकता है। टेस्टेबल ऑब्जेक्ट्स में कोड ले जाकर, आपके कंट्रोलर छोटे, समझने में आसान, और खुद को टेस्ट करने में आसान हो जाएंगे।
क्या मुझे यह एक नंबर वाली सूची के रूप में मिल सकता है?
एक बार फिर, एक बड़े कंट्रोलर को तोड़ने के लिए ये चरण हैं:
- कंट्रोलर के खिलाफ चल रहे उच्च-स्तरीय इंटीग्रेशन टेस्ट प्राप्त करें।
- टेस्ट चलाएं, सुनिश्चित करें कि वे पास होते हैं।
before_filters, सुपरक्लास मेथड, और अन्य अमूर्तताएं जो कोड छिपाती हैं, उन्हें इनलाइन करें।- टेस्ट चलाएं, सुनिश्चित करें कि वे अभी भी पास होते हैं।
- एक रिफैक्टरिंग करें (एक्सट्रैक्ट मेथड, एक्सट्रैक्ट सर्विस ऑब्जेक्ट, इंस्टेंस वेरिएबल को लोकल से बदलें, आदि)। देखें कि कोड कैसा महसूस होता है।
- टेस्ट चलाएं, सुनिश्चित करें कि वे अभी भी पास होते हैं।
- यदि आपने अभी कोड निकाला है, तो आपके द्वारा निकाले गए ऑब्जेक्ट या मेथड के खिलाफ कुछ यूनिट टेस्ट लिखें।
- टेस्ट चलाएं, सुनिश्चित करें कि वे अभी भी पास होते हैं।
- यदि कंट्रोलर को अभी भी काम की आवश्यकता है, तो चरण 5 पर वापस जाएं।
आगे क्या?
यदि आप अधिक सीखना चाहते हैं, तो Working Effectively with Legacy Code, बिना टेस्ट के अनुरक्षनीय कोड को लेने और इसे कुछ ऐसे में बदलने की बाइबिल है जिसके साथ आप काम कर सकते हैं। मैं इसकी अत्यधिक अनुशंसा करता हूं, यदि आप अक्सर विशाल मोनोलिथिक कंट्रोलर्स का सामना करते हैं (और यदि रिफैक्टरिंग आपके लिए उतना ही मजेदार है जितना मेरे लिए)।
तो अब, आइए आपकी डरावनी कहानियाँ सुनते हैं! अब तक का सबसे खराब कंट्रोलर कोड कैसा दिखता था?