Goodbye, clean code (2020)

कई इंजीनियरों का तर्क है कि DRY और आक्रामक abstraction जैसे “clean code” सिद्धांतों को कठोरता से लागू करने की कोशिश उलटी पड़ सकती है, जब वे लचीलेपन को कम करें और भविष्य के बदलावों को आसान के बजाय कठिन बना दें। Commenters दोहराए गए लेकिन सीधे, domain-specific code की तुलना abstracted versions से करते हैं जो असंबंधित मामलों को उलझा देती हैं, cognitive load बढ़ाती हैं, और अक्सर बहुत कम उदाहरणों से सामान्यीकरण की जल्दबाज़ी को दर्शाती हैं। एक बार-बार उभरने वाला विषय यह है कि maintainability उतनी ही good judgment, communication, और context-aware tradeoffs पर निर्भर करती है जितनी किसी खास style rule या design dogma पर।

क्लीन कोड, DRY, और एब्स्ट्रैक्शन

  • कई लोग तर्क देते हैं कि रिफैक्टर असफल हुआ क्योंकि उसने एक खराब एब्स्ट्रैक्शन बनाया, न कि इसलिए कि “क्लीन कोड” स्वभावतः बुरा है।
  • DRY को एक मार्गदर्शक सिद्धांत माना जाता है: यह तब उपयोगी है जब कई जगहों को हमेशा साथ-साथ बदलना चाहिए; और तब हानिकारक है जब यह असंबंधित मामलों को एक ही रास्ते में मजबूर कर दे।
  • कई टिप्पणियाँ इस पर ज़ोर देती हैं: “टॉप-डाउन नहीं, बॉटम-अप एब्स्ट्रैक्ट करें”—पहले ठोस उपयोग-केस जमा होने दें, फिर सरल, स्पष्ट हेल्पर्स को अलग करें।
  • एक बार-बार आने वाला heuristic: ज्ञान या व्यवहार की duplication को abstraction की ज़रूरत होती है; कोड की आकृति में सतही समानता अक्सर नहीं।

जब Duplication बेहतर हो

  • कई पोस्टर कहते हैं, “गलत abstraction से duplication सस्ती है।” गलत abstractions brittle हो जाते हैं, conditionals और special cases जोड़ते हैं, और उन्हें वापस खोलना मुश्किल होता है।
  • विकसित होते domains (graphics, finance products, complex business logic) में, अलग-अलग लेकिन मिलती-जुलती code paths रखना अक्सर भविष्य में divergence के लिए लचीलापन बनाए रखता है।
  • कुछ लोग बताते हैं कि एक ही logic को कुछ जगहों पर edit करना शायद ही असली cost driver होता है; उलझी हुई abstraction को debug करना अक्सर होता है।

“Clean Code” Canon का आकलन

  • कुछ लोग “Clean Code” शैली की आलोचना करते हैं कि वह dogmatic है, कम caveats वाली है, और juniors को आकर्षित करती है जो नियमों को यांत्रिक ढंग से लागू करते हैं (जैसे, “बहुत सारे छोटे functions,” हर कीमत पर DRY)।
  • अन्य लोग नोट करते हैं कि मूल texts recommendations को विवादास्पद और गैर-अधिकारिक रूप में प्रस्तुत करते हैं, और ज़ोर देते हैं कि misuse पाठक की गलती है, किताब की नहीं।
  • चिंता यह है कि linters और teams ने लचीली guidelines को कठोर doctrine में बदल दिया है।

टीम गतिशीलता और प्रक्रिया

  • कई लोगों के अनुसार मूल गलती सामाजिक/प्रक्रियागत थी: रात में एक teammate के नए काम को फिर से लिख देना और चर्चा या review के बिना commit करना।
  • राय दो धड़ों में बँटती है: “code टीम का होता है; कोई भी refactor कर सकता है” और “context और etiquette मायने रखते हैं; एकतरफा rewrites trust को नुकसान पहुँचाते हैं।”
  • सुझाए गए विकल्प: review comments, incremental helper extraction, original author को शामिल करके अलग PRs।

भाषा और paradigm के दृष्टिकोण

  • कुछ लोग functional languages (जैसे Applicative/Monad laws वाली) की सराहना करते हैं क्योंकि वे standardized, reusable abstractions देती हैं, जिससे project-specific abstractions कम होती हैं।
  • अन्य लोग Go के विपरीत tradeoff को रेखांकित करते हैं: भाषा-स्तर की कम abstractions, अधिक duplication, लेकिन सरल mental model।
  • geometry के लिए object-oriented hierarchies (जैसे squares बनाम rectangles) और यह कि mutability naive abstractions को कैसे तोड़ देती है, इस पर बहस है।

Testing, Maintainability, और Practicality

  • एक पक्ष का तर्क है कि भारी testing से “fearless refactoring” संभव होता और यह बदलाव विवादास्पद नहीं रहता।
  • दूसरे जवाब देते हैं कि tests cognitive complexity या सामाजिक मुद्दों को हल नहीं करते; सौंदर्यात्मक या संरचनात्मक रूप से खराब code पूरी तरह tested हो सकता है और फिर भी हानिकारक रह सकता है।
  • व्यापक सहमति: maintainability, business logic की स्पष्टता, और change की आसानी aesthetics या line-count घटाने से ऊपर हैं।