- सॉफ़्टवेयर में बहुत-सी चीज़ें अनिश्चित होती हैं।
- ऐसा अनिश्चित क्यों है?
- सबसे बड़ा कारण यह है कि बिज़नेस की जटिलता मौजूद होती है
- जटिलता के कारण परिस्थितियाँ लगातार बदलती रहती हैं, और इस वजह से डेवलपर की भविष्यवाणियाँ बहुत अधिक संभावना के साथ गलत साबित होती हैं।
- मेहनत से बनाया गया टॉवर ढह जाता है और वैसा ही technical debt में बदल जाता है।
- एक छोटा कारण ज्ञान और अनुभव की कमी भी है
- यदि ज्ञान और अनुभव न हों, तो डेवलपर स्वयं अपने हाथों से technical debt बना सकता है
- बिज़नेस की जटिलता ऐसे बाहरी कारण हैं जिन्हें डेवलपर नियंत्रित नहीं कर सकता, जबकि ज्ञान और अनुभव ऐसे आंतरिक कारण हैं जिन्हें डेवलपर नियंत्रित कर सकता है
- डेवलपर के सामने तीन रास्ते होते हैं
- निराशावादी रास्ता, जिसमें यह माना जाता है कि जटिलता का सामना करना निरर्थक है
- तब लोग कहते हैं, ‘वैसे भी बदलने वाला है, बस कर दो’, ‘तकनीक का कोई मतलब नहीं है’
- यह आसान और आरामदेह रास्ता है, इसलिए अनजाने में भी कोई इस रास्ते को चुन सकता है
- वह रास्ता जो जटिलता की अनदेखी करता है और केवल आदर्श कल्पना के बारे में सोचता है
- यह विश्वास कि जिस एक तकनीक को आप आदर्श मानते हैं, उसी से सब कुछ हल किया जा सकता है
- इससे कठोर और एकरूपी सोच विकसित हो जाती है
- डेवलपर आसानी से इस रास्ते में फँस सकते हैं, लेकिन इससे बाहर निकलना कठिन होता है
- वह रास्ता जो जटिलता को स्वीकार करता है और उससे लड़ता है
- यह स्वीकार करने के बाद भी कि पूर्णता संभव नहीं है, लगातार बेहतर रास्ता खोजते रहना
- यह कठिन रास्ता है, और इसे सहना पड़ता है
- सॉफ़्टवेयर विकास लगातार जटिलता से लड़ता आया है
- architecture, methodology, Agile आदि…
- आगे क्या सामने आएगा?
- विनाश-उन्मुख विकास
- वास्तविकता को देखते हुए यह निराशावादी सोच में फँसना आसान है कि वैसे भी सब मिटा दिया जाएगा।
- क्योंकि जो कोड हमने मेहनत से लिखा है, उसे असफल रचना मानकर खुद मिटाना बहुत पीड़ादायक होता है
- तो क्यों न उल्टा सोचें और उसे इस तरह बनाएँ कि उसे अच्छे से मिटाया जा सके?
- क्या विनाश अच्छी चीज़ है?
- विनाश के बिना नया जन्म नहीं ले सकता
- सॉफ़्टवेयर में दिखने वाले विनाश के दो बड़े रूप हैं - pivot और refactoring
- pivot संगठन और उत्पाद को बेहतर रास्ता चुनने में मदद करता है
- refactoring सॉफ़्टवेयर की उम्र बढ़ाने के लिए अनिवार्य काम है
- तो विनाश-उन्मुख विकास क्या है?
- यह एक ऐसी कार्यप्रणाली है जो इस तथ्य को स्वीकार करती है कि किसी दिन कोड नष्ट होगा, और उसी को ध्यान में रखकर विकास करती है
- यह तीन बड़े सिद्धांतों की ओर उन्मुख है
- यदि अनिश्चितता है, तो जहाँ तक संभव हो उसे कम करें।
- यदि कई तरीकों में से चुनना हो, तो वह तरीका चुनें जिसे नष्ट करना आसान हो।
- केवल आवश्यक चीज़ों को बनाए रखें। इसलिए जो आवश्यक नहीं है, उसे पूरी तरह हटा दें।
- विश्लेषण -> सीमा-विभाजन -> कोड इम्प्लीमेंटेशन -> जटिलता हटाना
- मुख्य बात यह है कि आंतरिक कारणों से उत्पन्न अनिश्चितता को कम किया जाए और अपरिहार्य बाहरी कारणों से होने वाले विनाश के लिए तैयार रहा जाए
- सीमा-विभाजन
- अनिश्चितता परिवर्तन-दर है, और इसके आधार पर विभाजन किया जा सकता है
- डेवलपर को बाहरी कारणों के लिए तैयार रहना चाहिए और आंतरिक कारणों से होने वाली परिवर्तन-दर को यथासंभव कम करना चाहिए
- प्रत्येक कारण की परिवर्तन-दर संगठन के अनुसार अलग हो सकती है, इसलिए इसे स्थिर संख्यात्मक मान से व्यक्त करना संभव नहीं है -> इसे heuristic तरीकों से मापा जाता है
- ex) story point measurement
- यह तय करना होगा कि किस आधार पर विभाजन किया जाएगा, यानी abstraction level निर्धारित करना होगा
- विनाश-योग्यता
- इम्प्लीमेंटेशन करते समय बड़े सिद्धांतों के अनुसार वही विकल्प चुनें जिसे नष्ट करना आसान हो
- independence, recognizability, controllability को ध्यान में रखकर विनाश-योग्यता का आकलन किया जा सकता है
- independence का आकलन coupling और cohesion की डिग्री, और single responsibility principle को किस हद तक निभाया गया है, इससे किया जाता है
- recognizability का अर्थ है कि डेवलपर कोड को देखकर उसे किस हद तक समझ सकता है
- controllability का अर्थ है यह तय करना कि क्या वह ऐसा क्षेत्र है जिसे डेवलपर नियंत्रित कर सकता है
- जटिलता हटाना
- यह जाँचना और हटाना चाहिए कि कहीं कुछ अनावश्यक तो नहीं है। यानी अंततः codebase में केवल आवश्यक चीज़ें ही बची रहनी चाहिए
- यदि deadline जैसी समस्याओं के कारण इस पर काम करना कठिन हो, तो केवल इसे रिकॉर्ड करके बाद में काम करना भी ठीक है
- क्योंकि आंतरिक कारण नियंत्रित किए जा सकते हैं
- विनाश की तैयारी में यथासंभव सरलता बनाए रखना ही मुख्य बात है
- कोड विनाश की तकनीकें
- कोड को अच्छी तरह हटाने के लिए कई सिद्धांत और तरीके हैं
- चरणों में बाँटना (refactoring pattern)
- referential transparency बनाए रखना
- single responsibility principle का पालन करना
- interface segregation principle का पालन करना
- strangler fig pattern
- method specialization
- duplicate code लिखना
- परिवर्तन-दर का रिकॉर्ड रखना
6 टिप्पणियां
यह बात कि ज्ञान और अनुभव की कमी की वजह से code debt बनता है, मुझसे ज़्यादा मेल नहीं खाती।
-> हो सकता है requirements को implement करने के लिए दिया गया समय कम हो, और collaboration की स्थिति में दूसरों के साथ तालमेल रखने के लिए थोड़ा technical debt स्वीकार करना पड़े; मुझे लगता है कि परिस्थितियाँ कई तरह की हो सकती हैं.
यह भी मुझे ठीक से समझ नहीं आता कि ज्ञान और अनुभव को developer के नियंत्रण में रहने वाले आंतरिक कारक माना जाए।
-> business जटिल होता है, इसलिए यह अनुमान लगाना संभव नहीं कि कौन-सी स्थिति सामने आएगी, और हर संभावना के लिए उसी समय पढ़ाई भी नहीं की जा सकती। उस स्थिति का सामना होने पर पढ़ भी लें, तब भी अगली बार पूरी तरह नई समस्या आ सकती है और वह ज्ञान बेकार हो सकता है।
नमस्ते। अपनी राय साझा करने के लिए धन्यवाद।
मेरा मानना है कि जब हम किसी बात को उसके चरम पर रखकर देखते हैं, तभी उसके सार को ठीक से समझ पाते हैं। इसी दृष्टि से देखें तो, अगर ‘ज्ञान और अनुभव’ पूरी तरह से मौजूद हों, तो समय सीमा के भीतर technical debt नहीं बल्कि सही code बनाया जा सकता है।
समय की कमी को दो हिस्सों में बाँटा जा सकता है। पहला, जब implementation के लिए आवश्यक समय सचमुच कम हो। इस स्थिति में, ज्ञान और अनुभव से अलग, code लिखने के लिए physical time ही कम पड़ जाता है। इसलिए शुरुआत से ही लक्ष्य हासिल करना असंभव हो जाता है। दूसरा, जब यह समझने का समय कम हो कि क्या बेहतर है। ऐसे में implementation का तरीका समझने या उससे बेहतर विकल्प खोजने का समय नहीं होता, इसलिए हम केवल अपने मौजूदा ज्ञान के आधार पर code लिखकर काम खत्म कर देते हैं। इस तरह काम पूरा तो हो जाता है, लेकिन यह एहसास बना रहता है कि ‘कहीं न कहीं कुछ गलत है’, पर ठीक-ठीक कैसे सुधारना है यह पता नहीं होता। अगर सटीक ज्ञान होता और उससे जुड़ा अनुभव आत्मविश्वास देता, तो शायद ऐसी समस्या पैदा नहीं होती।
ऊपर लिखी समय की कमी वाली बात मुझे लगता है कि मेरे विचार का समर्थन करती है। बेशक, वास्तविकता में यह बहुत कठिन समस्या है। मैंने तो बस एक आदर्श स्थिति की बात की है। ज्ञान और अनुभव से पूरी तरह सुसज्जित अवस्था बहुत कम होती है, और जैसा आपने कहा, संगठन के लिए जानबूझकर कुछ चीजें सहन करनी पड़ती हैं, ऐसे मामले भी निश्चित रूप से होते हैं। उसमें असहजता या खिन्नता हो सकती है, लेकिन मैं इस समस्या को ‘अगर चरम रूप में देखें’ तो ज्ञान और अनुभव की कमी से उत्पन्न समस्या मानता हूँ।
दूसरे बिंदु में आपने जो internal factor कहा, वह सरल है। ‘बिज़नेस जटिल होता है, इसलिए यह अनुमान नहीं लगाया जा सकता कि कौन-सी स्थिति सामने आ जाएगी …’ यह हिस्सा मेरे लिखे हुए लेख में ‘बिज़नेस की जटिलता’ पर की गई चर्चा से जुड़ा है। यानी, यह बाहरी कारकों से पैदा होने वाली समस्या है। चूँकि यह बाहरी कारक है, developer इसे नियंत्रित नहीं कर सकता और उसी वजह से भय महसूस करता है। इसे भी अगर चरम दृष्टि से देखें और मान लें कि बिज़नेस की जटिलता है ही नहीं, तो अंततः केवल developer द्वारा लिखा गया code ही बचता है। तब भीतर से नियंत्रित किए जा सकने वाले ‘ज्ञान और अनुभव’ का प्रश्न ही शेष रह जाता है।
बेशक, मैंने जो लिखा है वह भी सिर्फ मेरी राय है। इसके पर्याप्त counterexamples हो सकते हैं। मेरा मानना है कि विचारों का आदान-प्रदान बेहतर रास्ते तक पहुँचने का एक अवसर है। आगे भी अपने विचार साझा करते रहें। धन्यवाद।
कृपया उत्तर देने के लिए धन्यवाद।
लेख बहुत अच्छा लगा। लगता है कि संगठन किस stage में है, उसके अनुसार यह भी बदलता है कि क्या early optimization है और क्या overengineering। मुश्किल बात यही है कि यह ऐसा code भी है जिसे वैसे भी फिर से लिखना पड़ सकता है, और साथ ही ऐसा code भी है जिसके लिए शायद वह दोबारा लिखने का क्षण आए या न आए। मैं कभी-कभी यह सवाल पूछकर भी निर्णय लेता हूँ कि अगर xxx service या feature हट जाए, तो yyy code और data का कहाँ होना उचित होगा? दूसरे लोग किस तरह तय करते हैं, यह भी जानने की उत्सुकता है।
मैं यह भी सोचता/सोचती हूँ कि सिर्फ कोड ही नहीं, बल्कि डेटा या स्कीमा भी हट सकते हैं या बदले जा सकते हैं।
मैं डेटा के बारे में भी कुछ शामिल करना चाहता था, लेकिन उसे ठीक से सोचना मुश्किल लग रहा था। यह एक critical हिस्सा है, इसलिए इसे आसानी से छेड़ना मुश्किल है, और ज़रा सी गलती से migration hell में फँसने का जोखिम भी है, इसलिए मैं सावधान था.
जैसा आपने कहा, शुरुआती design चरण बहुत महत्वपूर्ण लगता है। मेरा मानना है कि मुख्य बात यह होगी कि RAW को जितना हो सके उतना अच्छी तरह accumulate किया जाए। या फिर event sourcing architecture, deletion के पहलू से, फ़ायदेमंद हो सकता है। बेशक, मैंने उस architecture को वास्तव में ठीक से इस्तेमाल नहीं किया है, इसलिए यह सच में कितना valid होगा, इस बारे में मैं निश्चित नहीं हूँ.