DanLevy.net

एक‑उद्देश्य लोगों से सावधान रहें

इतना शुद्ध किदर्द देता है

SingleResponsibility Principle उन विचारों में से एक है जो इतनी समझदार लगती है कि आपके निर्णय को चुपके से पार कर लेती है।

एक ही काम करें। उसे ठीक से करें। मॉड्यूल को केंद्रित रखें। कोड को बदलने का कारण दें। अच्छा सलाह।

फिर कोई इस सलाह को मापने की टेप बना लेता है और कहता है कि पाँच लाइनों से अधिक वाली कोई भी फ़ंक्शन कोड की बदबू है।

समस्या SRP नहीं है। समस्या यह है कि “छोटा” को “संगत” का विकल्प मान लिया गया है।

उस बिंदु पर आप Single-Purpose People से मिलते हैं: ऐसे डेवलपर जो मॉड्यूलरिटी के बारे में बिल्कुल गलत नहीं हैं, लेकिन उपयोगी सीमाओं को अधिकतम विखंडन के साथ भ्रमित कर देते हैं।

सॉफ़्टवेयर आर्किटेक्चर में हिंसा
Components, components everywhere

I. नीचे का उपयोगी विचार

फ़ॉर्म में एक ही चेकबॉक्स जोड़ना आदर्श रूप से केवल एक फ़ाइल को प्रभावित करना चाहिए। 5 डायरेक्टरी में 8 फ़ाइलों नहीं… मैं तुम्हें देख रहा हूँ, React/Redux.

जब SRP को समझदारी से लागू किया जाता है, तो यह मदद करता है। एक ही अवधारणात्मक कार्य पर केंद्रित कोड इकाइयाँ समझने में आसान होती हैं। परीक्षण व्यवहार को एक समझदार सीमा पर लक्षित कर सकते हैं। स्पष्ट मॉड्यूल यह आसान बनाते हैं कि सिस्टम के एक भाग को बदला जाए बिना बाकी एप्लिकेशन को कमरे में खींचे।

यहाँ तक कि क्लासिक Unix उदाहरण भी नारा जितना सिद्धांतवादी नहीं, बल्कि व्यावहारिक होते हैं। ls फ़ाइलों की सूची देता है, हाँ, लेकिन यह opendir, readdir, closedir, और stat जैसी कॉलों का समन्वय भी करता है। उपयोगी इकाई सबसे छोटा संभव ऑपरेशन नहीं है। उपयोगी इकाई वह सबसे छोटा सुसंगत भाग है जो कार्य को हल करता है।

मूल Unix दर्शन संयोजन और सरलता के बारे में था, सब कुछ को एक ही फ़ंक्शन या फ़ाइल में घटाने के बारे में नहीं।

यह अंतर महत्वपूर्ण है। “एक ज़िम्मेदारी” का मतलब “एक लाइन का व्यवहार” नहीं है।

##II. Over-Abstraction: When Simplicity Turns to Chaos

Our architect insists every function longer than 5 lines is a ‘code smell’. Our codebase now smells faintly of clueless desperation.

विफलता का मोड आसानी से दिख जाता है, जब वह पहले ही आपके हफ़्ते को ख़राब कर चुका होता है।

कोडबेस में फ़ाइलें तो बढ़ गई हैं, लेकिन संरचना घट गई है। हर हेल्पर का एक और हेल्पर है। हर अवधारणा को फ़ोल्डरों में बाँट दिया गया है जो तकनीकी भूमिकाओं के नाम पर हैं, न कि उत्पाद के अर्थ पर। एक चेकबॉक्स जोड़ने के लिए आपको एक कंपोनेंट, एक हुक, एक सेलेक्टर, एक एक्शन, एक रिड्यूसर, एक कॉन्स्टेंट, एक टेस्ट फ़िक्स्चर, और एक बैरल एक्सपोर्ट छूना पड़ता है, जो मुख्यतः इम्पोर्ट पाथ को दोषी दिखने से बचाने के लिए मौजूद है।

इस अनंत कार्य पैटर्न से कोई बचाव नहीं
कंपोनेंट्स, हर जगह कंपोनेंट्स

इन सभी शुद्धता से आखिर क्या मिला?

मैंने कोड‑बेस के उस अंधकार में देखा है जहाँ एक सीधी‑सादी 100‑लाइन फ़ीचर को 15+ फ़ाइलों में विभाजित किया गया था, प्रत्येक “शुद्ध” छोटा फ़ाइल शायद एक या दो फ़ंक्शन रखती थी। उस गड़बड़ी को अपने दिमाग में रखने की संज्ञानात्मक ब्लास्ट‑रेडियस किसी भी सैद्धांतिक विभाजन‑लाभ को पूरी तरह नकार देती है। यह सरल नहीं था; यह बस बिखरा हुआ था।

III. पूर्णता की कीमत: डेवलपर्स पर प्रभाव

हम फ़ाइल संरचना और नामकरण नियमों पर फीचर शिप करने से अधिक समय बिता रहे हैं। क्या यह एजाइल है?

इतना गंदा कि कला की सीमा पर
इतना गंदा कि कला की सीमा पर

यह रोगात्मक विखंडन केवल सौंदर्य समस्या नहीं है। यह बदलता है कि डेवलपर्स अपना ध्यान कैसे खर्च करते हैं:

उत्पादकता का रिसाव: तकनीकी ऋण को भूल जाइए; यह व्यवस्थित ऋण है जो अत्यधिक डिरेक्टरी नेस्टिंग से जमा होता है। हर छोटे‑से‑छोटे बदलाव को अबstraction की परतों में खोदना पड़ता है। समय cd .. और grep की काली गहराई में गायब हो जाता है।

परीक्षण कर: भरोसा देने के बजाय, टेस्ट सूट घर्षण का स्रोत बन जाता है। तुच्छ रीफ़ैक्टर से टूटे टेस्टों को ठीक करने में घंटे बिखर जाते हैं, ऐसे टेस्ट जो बहुत ही सूक्ष्म विवरणों से बंधे होते हैं जिन्हें वे सत्यापित करने वाले थे।

संज्ञानात्मक भार: मानव मस्तिष्क कितनी असंबद्ध जानकारी को एक साथ संभाल सकता है, इसकी एक कठोर सीमा है। डेवलपर्स को दर्जनों बिखरे फ़ाइलों से प्रोग्राम प्रवाह को जोड़ने के लिए मजबूर करना समझ को बाधित करता है और आत्मविश्वासपूर्ण बदलाव करना कठिन बनाता है।

IV. व्यावहारिकता को अपनाना: एक ठोस विकल्प

मैंने सुझाव दिया कि दो संबंधित फ़ंक्शन एक ही फ़ाइल में रखें। कमरे ने ऐसा प्रतिक्रिया दी जैसे मैंने स्टेजिंग को हटाने की पेशकश की हो। — एक पुनरुज्जीवित शुद्धतावादी पाठक

एस्केप हैच SRP को छोड़ना नहीं है। उत्तर है इसे सही अर्थ स्तर पर लागू करना।

यहाँ इसका व्यावहारिक रूप दिया गया है:

लक्ष्य सैद्धांतिक पूर्णता नहीं है जो पीएचडी थीसिस के योग्य हो; यह ऐसा कोड बनाना है जिसे आपके सहयोगी (और भविष्य का आप) बिना इमारत को आग लगाने की इच्छा के नेविगेट, समझ और संशोधित कर सकें।

कभी‑कभी इसका मतलब है कि फ़ाइल 200 पंक्तियों की हो बजाय 50 की। कभी‑कभी एक फ़ंक्शन डेटा लाने और उसे थोड़ा बदलने दोनों का काम करता है। कभी‑कभी एक क्लास में दो ज़िम्मेदारियाँ इतनी कसकर जुड़ी होती हैं कि उन्हें साथ रहना चाहिए। यदि यह सिस्टम को कुल मिलाकर काम करने में आसान बनाता है, तो यह संभवतः सही निर्णय है।

व्यावहारिक प्रश्नों पर अडिग रहें:

V. निष्कर्ष: सुसंगत और रखरखाव‑योग्य कोड को प्रोत्साहित करना

Single Responsibility Principle एक उपयोगी उपकरण है। यह आपके कोडबेस को परमाणु धूल में बदलने का आदेश नहीं है। किसी भी उपकरण की तरह, इसकी मूल्यांकन उपयोगकर्ता के निर्णय पर निर्भर करती है।

इसलिए जब आप “Single‑Purpose People” से मिलें, जो किसी भी फ़ंक्शन को जो तीन पंक्तियों से अधिक हो, युद्ध की घोषणा करने को तैयार हों, तो एक साँस लें। 12‑फ़ाइल चेकबॉक्स को याद रखें।

हमारा काम सिद्धांत‑परक रूप से परिपूर्ण स्नोफ़्लेक फ़ंक्शन बनाना नहीं है। हमारा काम ऐसा सॉफ़्टवेयर बनाना है जो काम करे, समस्याओं का समाधान करे, और अगले व्यक्ति को दंडित न करे जो इसे छूता है।

व्यावहारिक रहें। परिणामों पर ध्यान दें। शुद्धता की अति‑खोज को रखरखाव‑योग्य कोड का दुश्मन न बनने दें। आपका मनोबल, और आपकी टीम की गति, इसी पर निर्भर करती है।

¹ विडंबना यह है कि सबसे निचले स्तर पर वास्तविक एकल उद्देश्य प्राप्त करने के लिए सतह के ठीक नीचे विशाल जटिलता छिपी होती है।

² यहाँ हम अवधारणात्मक शुद्धता की बात कर रहे हैं: यह विचार कि एक फ़ंक्शन को केवल “एक ही चीज़” तार्किक रूप से करनी चाहिए। इसे फ़ंक्शनल प्रोग्रामिंग के “शुद्ध फ़ंक्शन” (जिसमें कोई साइड‑इफ़ेक्ट नहीं) से मत मिलाएँ; वह एक अलग, हालांकि कभी‑कभी संबंधित, अवधारणा है।