DRY (Don't Repeat Yourself) एक मौलिक डेवलपमेंट सिद्धांत है जिसे एंडी हंट और डेव थॉमस ने पुस्तक “The Pragmatic Programmer” में प्रतिपादित किया। यह कहता है: सिस्टम में ज्ञान के प्रत्येक भाग का एक ही, स्पष्ट, आधिकारिक प्रतिनिधित्व होना चाहिए। The Pragmatic Programmer, 20th Anniversary Edition के अनुसार, DRY का उल्लंघन करने का मतलब है कि एक तत्व को बदलने के लिए दर्जनों स्थानों पर संपादन की आवश्यकता होती है, और प्रत्येक छूटा हुआ टुकड़ा बग का स्रोत बन जाता है।
मुख्य बातें
DRY (Don't Repeat Yourself) एक डेवलपमेंट सिद्धांत है जो प्रोजेक्ट में प्रत्येक ज्ञान तत्व को बिल्कुल एक बार संग्रहीत करने की आवश्यकता रखता है। इसका मतलब है कि कोई भी लॉजिक, कॉन्फ़िगरेशन या मेटाडेटा केवल एक ही स्थान पर मौजूद होना चाहिए।
यह शब्द एंडी हंट और डेव थॉमस द्वारा 1999 में पुस्तक “The Pragmatic Programmer” में पेश किया गया था। लेखकों ने DRY को परिभाषित किया “ज्ञान के प्रत्येक भाग का सिस्टम के भीतर एक ही, स्पष्ट, आधिकारिक प्रतिनिधित्व होना चाहिए।” DRY के विपरीत WET (Write Everything Twice) दृष्टिकोण है, जहाँ डुप्लिकेशन को सामान्य माना जाता है।
University of California, Davis (2019) के एक अध्ययन के अनुसार, उच्च स्तर के कोड डुप्लिकेशन वाले प्रोजेक्ट बग ठीक करने में 42% अधिक समय बिताते हैं। कारण यह है कि डेवलपर्स को एक ही टुकड़े की सभी प्रतियां ढूंढनी और बदलनी होती हैं — और मैन्युअल खोज में अनिवार्य रूप से चूक होती है।
DRY को कोड गुणवत्ता मानदंड के रूप में लागू करें। यदि आप देखते हैं कि एक ही पैटर्न प्रोजेक्ट में तीन बार दिखाई देता है — चौथी पुनरावृत्ति की प्रतीक्षा किए बिना इसे एब्स्ट्रैक्शन में निकालें।
SOLID से एकल उत्तरदायित्व सिद्धांत (SRP) कहता है कि एक क्लास में बदलाव का एक ही कारण होना चाहिए। DRY व्यापक है: यह न केवल क्लास बल्कि डेटा, कॉन्फ़िगरेशन, दस्तावेज़ीकरण और यहां तक कि व्यावसायिक नियमों को भी कवर करता है। SRP जिम्मेदारी की सीमाओं के बारे में है; DRY कॉपी करने से रोकने के बारे में है।
मोबाइल डेवलपमेंट में, यह अंतर विशेष रूप से ध्यान देने योग्य है। यदि एक ही व्यावसायिक नियम (कर गणना, दिनांक स्वरूपण) प्रोजेक्ट के Android और iOS दोनों भागों में दोहराया जाता है — तो यह DRY का उल्लंघन है, भले ही SRP औपचारिक रूप से प्रत्येक प्लेटफ़ॉर्म के भीतर पालन किया जाता हो। समाधान सामान्य लॉजिक को साझा मॉड्यूल (KMM, C++) में निकालना है।
Google Android Architecture Guidelines (2023) रिपोर्ट के अनुसार, व्यावसायिक लॉजिक के लिए साझा मॉड्यूल का उपयोग करने वाली टीमें आवश्यकताओं में बदलाव पर प्लेटफ़ॉर्म पर लॉजिक डुप्लिकेट करने वाले प्रोजेक्ट की तुलना में बग की संख्या 37% कम करती हैं।
डुप्लिकेशन मोबाइल प्रोजेक्ट्स में तकनीकी ऋण का मुख्य स्रोत है। प्रत्येक कोड कॉपी एक छिपी निर्भरता बनाती है: व्यवहार बदलने के लिए, आपको सभी प्रतियां ढूंढनी और अपडेट करनी होंगी। एक को भी छोड़ने का मतलब है बग।
एक क्लासिक परिदृश्य पर विचार करें: एक Android ऐप में, दिनांक स्वरूपण तीन अलग-अलग Activities में किया जाता है। नए प्रारूप (जैसे ISO 8601) पर स्विच करते समय, डेवलपर दो फ़ाइलों को ठीक करता है, तीसरी को भूल जाता है — और उपयोगकर्ता पुराने प्रारूप में दिनांक देखता है। ऐप रेटिंग गिर जाती है, और बग ढूंढने में दोगुना समय लगता है।
Google Research (2020) के एक अध्ययन से पता चला कि मोबाइल एप्लिकेशन में 68% महत्वपूर्ण बग डुप्लिकेट कोड में असमकालिक परिवर्तनों से संबंधित हैं। इसके अलावा, प्रोडक्शन में ऐसे बग को ठीक करने की लागत 4.5 गुना अधिक होती है, अगर कोड शुरू से ही एकीकृत होता।
स्टैटिक विश्लेषकों (Detekt, SwiftLint) का उपयोग उन नियमों के साथ करें जो copy-paste का पता लगाते हैं। CI को कॉन्फ़िगर करें ताकि N से अधिक पंक्तियों के डुप्लिकेशन वाले पुल रिक्वेस्ट बिना औचित्य के समीक्षा पास न करें।
एक विशिष्ट एंटी-पैटर्न है RecyclerView एडेप्टर को मामूली संशोधनों के साथ कॉपी करना। एक सार्वभौमिक एडेप्टर के बजाय, डेवलपर प्रत्येक स्क्रीन के लिए एक अलग क्लास बनाते हैं। सामान्य बेस क्लास निकालकर रिफैक्टरिंग कोड को 30–50% तक कम कर देती है।
// डुप्लिकेशन: दो अलग-अलग एडेप्टर
class UserAdapter {
fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
fun bind(item: Product) { /* ... */ }
}
// DRY रिफैक्टरिंग: सामान्य बेस क्लास
abstract class BaseAdapter<T> {
abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }
पहले उदाहरण में, प्रत्येक एडेप्टर बाइंड तंत्र को शुरू से फिर से लागू करता है। नया लॉजिक (एनालिटिक्स, लॉगिंग) जोड़ते समय, हर फ़ाइल को बदलना होगा। एक बेस क्लास इस डुप्लिकेशन को समाप्त करती है: सामान्य लॉजिक एक जगह रहता है, विशिष्ट लॉजिक उपवर्गों में।
iOS प्रोजेक्ट्स में, URLSession कॉन्फ़िगरेशन — हेडर, टाइमआउट, त्रुटि प्रबंधन — अक्सर डुप्लिकेट किया जाता है। प्रत्येक सेवा दोहराई गई सेटिंग्स के साथ अपना सत्र बनाती है।
// डुप्लिकेशन: प्रत्येक सेवा सत्र को नए सिरे से कॉन्फ़िगर करती है
class UserService {
let session = URLSession(configuration: {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return cfg
}())
}
// DRY: एकीकृत सत्र फैक्ट्री
struct NetworkConfig {
static var session: URLSession {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return URLSession(configuration: cfg)
}
}
कॉन्फ़िगरेशन को एकीकृत NetworkConfig में निकालने से सुनिश्चित होता है कि सभी सेवाएँ समान हेडर और टाइमआउट का उपयोग करें। एक जगह बदलाव स्वचालित रूप से सभी अनुरोधों पर लागू होता है — यह API कुंजी या प्रोटोकॉल संस्करण बदलने पर त्रुटियों के जोखिम को कम करता है।
इनहेरिटेंस डुप्लिकेशन को खत्म करने का एक प्राकृतिक तरीका है: सामान्य लॉजिक को बेस क्लास में ले जाया जाता है, और विशिष्ट लॉजिक को उपवर्गों में। हालांकि, मोबाइल डेवलपमेंट में, इनहेरिटेंस का अत्यधिक उपयोग कठोर पदानुक्रम बनाता है जिसे बनाए रखना मुश्किल होता है। कम्पोज़ीशन (डिपेंडेंसी इंजेक्शन) एक अधिक लचीला विकल्प है।
Google I/O 2023: Modern Android Architecture के एक विश्लेषण से पता चला कि 76% Google टीमें डुप्लिकेशन खत्म करने के लिए इनहेरिटेंस पर कम्पोज़ीशन पसंद करती हैं। दर्जनों विधियों वाले BaseViewModel के बजाय, प्रत्येक व्यावसायिक संचालन के लिए अलग UseCase क्लास निकालने और उन्हें ज़रूरत के स्थान पर इंजेक्ट करने की सिफारिश की जाती है।
“is-a” संबंधों को छोड़कर सभी मामलों में कम्पोज़ीशन चुनें। यदि क्लास A, क्लास B की विशेषज्ञता है — इनहेरिटेंस उपयुक्त है। यदि A केवल B की कार्यक्षमता का उपयोग करता है — कम्पोज़ीशन का उपयोग करें।
यूटिलिटी क्लास (Extensions, Helpers) डुप्लिकेशन से बचने का सबसे सरल तरीका है। विशिष्ट उम्मीदवार: दिनांक स्वरूपण, ईमेल सत्यापन, इकाई रूपांतरण, SharedPreferences/UserDefaults के साथ काम करना।
// DRY: एकीकृत दिनांक स्वरूपण फंक्शन
fun Date.toDisplayFormat(): String {
val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
return sdf.format(this)
}
// एप्लिकेशन में कहीं भी उपयोग
textView.text = Date().toDisplayFormat()
Date.toDisplayFormat() एक्सटेंशन एक बार घोषित किया जाता है और पूरे प्रोजेक्ट में उपलब्ध होता है। यदि प्रारूप को “dd.MM.yyyy” से “yyyy-MM-dd” में बदलने की आवश्यकता है — सुधार एक फ़ाइल में है, हर Activity या Fragment में नहीं जहाँ स्वरूपण होता है। यह DRY का सार है।
मल्टी-मॉड्यूल Android प्रोजेक्ट अक्सर प्रत्येक build.gradle में डिपेंडेंसी संस्करणों को डुप्लिकेट करते हैं। समाधान एक वर्जन कैटलॉग (libs.versions.toml) है जो सभी संस्करणों को एक फ़ाइल में केंद्रीकृत करता है।
Android डेवलपर दस्तावेज़ीकरण (2024) के अनुसार, वर्जन कैटलॉग में माइग्रेट करने से डिपेंडेंसी विरोध 52% कम होता है और संपादन के एकल बिंदु के माध्यम से बिल्ड गति बढ़ती है।
प्रोजेक्ट की शुरुआत में या पहले मॉड्यूल पुनर्गठन के दौरान वर्जन कैटलॉग लागू करें। यदि प्रोजेक्ट में पहले से ही डुप्लिकेशन है — माइग्रेशन के लिए एक दिन अलग रखें: यह अगली लाइब्रेरी अपडेट पर लाभदायक होगा।
समय से पहले एब्स्ट्रैक्शन शुरुआती लोगों की सबसे आम गलती है। एक डेवलपर कोड की दो समान पंक्तियाँ देखता है और तुरंत उन्हें एक सामान्य फंक्शन में निकाल लेता है। एक महीने बाद, आवश्यकताएँ बदल जाती हैं, और सामान्य फंक्शन पैरामीटर और फ़्लैग से भर जाता है — मूल डुप्लिकेशन से अधिक जटिल। Rule of Three इसी से बचाता है: उस चीज़ को एब्स्ट्रैक्ट न करें जो केवल एक या दो बार दिखाई दी हो।
मार्टिन फाउलर अपनी पुस्तक Refactoring (2019) में सलाह देते हैं: “कोड डुप्लिकेशन हमेशा बुरा नहीं होता। ज्ञान का डुप्लिकेशन बुरा होता है।” यदि दो पंक्तियाँ संयोग से मेल खाती हैं लेकिन अलग-अलग अवधारणाओं को व्यक्त करती हैं — यह डुप्लिकेशन नहीं है, यह संयोग है। Rule of Three आकस्मिक संयोग को व्यवस्थित डुप्लिकेशन से अलग करने में मदद करता है।
एब्स्ट्रैक्ट करने से पहले, शब्दार्थ का आकलन करें। समान अर्थ वाला कॉपी किया गया कोड — DRY का उल्लंघन। अलग अर्थ लेकिन समान सिंटैक्स वाला कोड — संयोग जिसे एब्स्ट्रैक्शन की आवश्यकता नहीं है।
अत्यधिक पैरामीटरीकरण तब होता है जब एक फंक्शन फ़्लैग और बूलियन पैरामीटर के माध्यम से सभी संभावित परिदृश्यों को कवर करने का प्रयास करता है। ऐसा कोड SRP का उल्लंघन करता है और अपठनीय हो जाता है। लक्षण: यदि किसी फंक्शन में दो से अधिक बूलियन पैरामीटर हैं — यह अत्यधिक एब्स्ट्रैक्शन का कोड स्मेल है।
useCache: Boolean फ़्लैग वाले एक फंक्शन के बजाय, स्पष्ट नामों वाले दो अलग-अलग फंक्शन बनाना बेहतर है: fetchFromNetwork() और fetchFromCache()। स्पष्टता सूखी एब्स्ट्रैक्शन से अधिक महत्वपूर्ण है — यह KISS सिद्धांत से मेल खाता है।
जब कोई फंक्शन 3+ बूलियन पैरामीटर तक पहुँचता है तो अत्यधिक पैरामीटरीकरण को रिफैक्टर करें। स्पष्ट नामों वाले अलग-अलग फंक्शन में विभाजित करें — प्रत्येक कॉल स्व-दस्तावेज़ीकरण बन जाएगा।
अक्सर पूछे जाने वाले प्रश्न
DRY (Don't Repeat Yourself) एक सिद्धांत है जो प्रत्येक तार्किक इकाई को एक ही स्थान पर संग्रहीत करने की आवश्यकता रखता है। यदि एक ही कोड प्रोजेक्ट के कई भागों में दिखाई देता है — यह DRY का उल्लंघन है। समाधान: दोहराए जाने वाले लॉजिक को एक अलग फंक्शन, क्लास या मॉड्यूल में निकालें।
WET (Write Everything Twice) DRY के विपरीत है, जहाँ डुप्लिकेशन स्वीकार्य माना जाता है। WET प्रोजेक्ट्स में, एक ही कोड टुकड़ा पाँच प्रतियों में मौजूद हो सकता है, और जब आवश्यकताएँ बदलती हैं, तो डेवलपर प्रत्येक प्रतिलिपि को अलग-अलग ठीक करता है। WET बग के जोखिम को बढ़ाता है और विकास को धीमा करता है।
DRY तब हानिकारक होता है जब यह समय से पहले एब्स्ट्रैक्शन की ओर ले जाता है: जब दो समान लेकिन शब्दार्थ रूप से भिन्न कोड अनुभागों को जबरन एक फंक्शन में जोड़ दिया जाता है। यह जटिल, पैरामीटर-भारी कोड उत्पन्न करता है। Rule of Three इस गलती से बचने में मदद करता है: तीसरी पुनरावृत्ति के बाद ही एब्स्ट्रैक्ट करें।
Android में, DRY को वर्जन कैटलॉग (libs.versions.toml), एडेप्टर के लिए सामान्य बेस क्लास, ViewModel फैक्ट्री और यूटिलिटी Kotlin एक्सटेंशन के माध्यम से लागू किया जाता है। व्यावसायिक लॉजिक को साझा मॉड्यूल (KMM) में निकालने और findViewById डुप्लिकेशन को खत्म करने के लिए View Binding का उपयोग करने की सिफारिश की जाती है।
iOS में, DRY डिफ़ॉल्ट कार्यान्वयन वाले प्रोटोकॉल, साझा नेटवर्क कॉन्फ़िगरेशन (NetworkConfig), UICollectionView सेल फैक्ट्री और सामान्य व्यावसायिक लॉजिक वाले SPM पैकेज के माध्यम से प्राप्त किया जाता है। मानक प्रकारों (Date, String, URL) के एक्सटेंशन स्वरूपण और सत्यापन में डुप्लिकेशन कम करते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें