मार्टिन फाउलर के व्यावहारिक नजरिए से जानें: पैटर्न, रिफैक्टरिंग और विकासशील आर्किटेक्चर जो फैशनेबल स्टैक्स से आगे टिकते हैं और दीर्घकालिक जोखिम घटाते हैं।

एक नया फ़्रेमवर्क, चमकता क्लाउड सर्विस, या किसी हॉट कंपनी का “स्टैंडर्ड स्टैक” गुणवत्ता का शॉर्टकट लग सकता है। लेकिन स्टैक-फर्स्ट सोच अक्सर टूल्स को संरचना से ग़लत तरीके से जोड़ देती है। आप सबसे आधुनिक तकनीकों के साथ एक गन्दा, बदलने में कठिन सिस्टम बना सकते हैं—या उबाऊ, परिचित विकल्पों के साथ एक साफ़, अनुकूलनीय सिस्टम।
स्टैक को पहले चुनना टीमों को उन निर्णयों की ओर धकेलता है जो स्लाइड पर प्रभावशाली दिखते हैं पर असल सवालों का जवाब नहीं देते:
जब टेक चॉइस नेतृत्व करती है, तो आर्किटेक्चर एक आकस्मिक उपोत्पाद बन जाता है—जिससे टाइट कपलिंग, डुप्लीकेट लॉजिक और ऐसे निर्भरता बनती हैं जो साधारण बदलावों को महँगा बना देती हैं।
इसलिए “हम माइक्रोसर्विसेस यूज़ कर रहे हैं” (या “अब हम सर्वरलेस हैं”) आर्किटेक्चर नहीं है। यह डिप्लॉयमेंट और टूलिंग दिशा है। आर्किटेक्चर इस बारे में है कि सिस्टम के हिस्से कैसे मिलकर काम करते हैं, फैसले भविष्य के काम को कैसे प्रतिबंधित करते हैं, और प्रोडक्ट कितनी आसानी से विकसित हो सकता है।
व्यावहारिक निहितार्थ: टूल्स डिलिवरी को तेज़ कर सकते हैं, पर वे आर्किटेक्चरल सोच की जगह नहीं ले लेते। आधुनिक “वाइब-कोडिंग” वाले तरीकों के साथ भी—जहाँ आप चैट के ज़रिए जल्दी जेनरेट और इटरेट करते हैं—उसी प्रकार के सवाल लागू होते हैं। प्लेटफ़ॉर्म जैसे Koder.ai वेब, बैकएंड और मोबाइल ऐप्स बनाने की गति बढ़ा सकते हैं, पर जो टीमें सर्वश्रेष्ठ परिणाम पाती हैं वे सीमाओं, स्वामित्व और बदलने की योग्यता को पहले दर्जे का मुद्दा मानती हैं (यह मानकर नहीं कि फ़्रेमवर्क जादुई रूप से समस्या हल कर देगा)।
मार्टिन फाउलर की लेखन शैली बार-बार ध्यान ऐसे मुद्दों की ओर वापस लाती है: फैशनेबल कंपोनेंट्स से ऊपर स्पष्ट डिज़ाइन, आइडियोलॉजी पर व्यावहारिक ट्रेड-ऑफ, और सीखने के साथ सिस्टम को विकसित करने की क्षमता। उनका काम आर्किटेक्चर को एक ऐसी चीज़ मानता है जिसे निरंतर बेहतर किया जाता है—ना कि एक बार का "बड़ा डिज़ाइन" माइलस्टोन।
तीन आवर्ती विषयों की उम्मीद करें: पैटर्न्स को वैकल्पिक टूल के रूप में उपयोग (नियम के रूप में नहीं), रिफैक्टरिंग को नियमित आदत के रूप में अपनाना, और विकासशील आर्किटेक्चर—बदलाव के लिए बनाना, निश्चितता के लिए नहीं।
अगर आप इंजीनियरिंग लीड हैं, टेक लीड हैं, या प्रोडक्ट टीम हैं जो क्वालिटी बिगड़ने बिना तेज़ी से शिप करना चाहती है, तो यह आपके लिए है। लक्ष्य “परफेक्ट” स्टैक चुनना नहीं है—बल्कि वे निर्णय लेना है जो सॉफ़्टवेयर को आसान बनाए रखें ताकि रोडमैप बदलने पर भी परिवर्तन सस्ता और सुरक्षित रहे।
सॉफ़्टवेयर आर्किटेक्चर उन निर्णयों का सेट है जो सिस्टम को इस तरह आकार देते हैं कि बाद में उन्हें बदलना कठिन (और महंगा) होता है।
यह परिभाषा जानबूझकर सादा है। इसे किसी खास डायग्राम या “आर्किटेक्ट” शीर्षक की ज़रूरत नहीं होती। यह उन चुनावों के बारे में है जो निर्धारित करते हैं कि सॉफ़्टवेयर कैसे बढ़ेगा, टीमें कैसे उस पर काम करेंगी, और इसे चलाने की लागत क्या होगी।
फ्रेमवर्क, टूल्स और कोडिंग स्टाइल मायने रखते हैं—पर अधिकतर इन्हें असली आर्किटेक्चरल चुनावों की तुलना में आसान बदला जा सकता है।
आर्किटेक्चर संरचना और सीमाओं के करीब है: सिस्टम के हिस्से कैसे संवाद करते हैं, डेटा कहाँ रहता है, विफलताओं को कैसे संभाला जाता है, और किन बदलावों के लिए टीमों का समन्वय चाहिए।
कोई सार्वभौमिक "सर्वोत्तम" आर्किटेक्चर नहीं है। हर बड़ा निर्णय कुछ लक्ष्यों के लिए अनुकूल करता है और दूसरों पर भार डालता है:
अच्छा आर्किटेक्चर इन ट्रेड-ऑफ को आकस्मिक नहीं बल्कि स्पष्ट बनाता है।
आर्किटेक्चरल फैसला: “हम ग्राहक बिलिंग को अपनी डिप्लॉयेबल सर्विस और अपनी डेटाबेस दे देंगे, और बाकी सिस्टम असिंक्रोनस इवेंट्स के जरिए इंटीग्रेट करेगा।”
इससे डिप्लॉयमेंट, डेटा ओनरशिप, फेलियर मोड, मोनिटरिंग और टीम समन्वय प्रभावित होंगे।
लाइब्रेरी चुनाव: “हम PDF जेनरेट करने के लिए लाइब्रेरी X का उपयोग करेंगे।”
उपयोगी है, पर आम तौर पर सीमित ब्लास्ट रेडियस के साथ बदला जा सकता है।
यदि किसी फैसले को पलटना करने में हफ्तों का समन्वय लगे, तो संभवतः वह आर्किटेक्चर है।
डिज़ाइन पैटर्न्स को बार-बार आने वाली समस्याओं के पुन:प्रयोगी समाधान के रूप में समझें, आदेशों के रूप में नहीं। फाउलर का सामान्य रुख व्यावहारिक है: जब पैटर्न डिज़ाइन को स्पष्ट करता है तो वह उपयोगी है, और जब वह सोच की जगह ले ले तो हानिकारक।
अच्छे उपयोग से, पैटर्न टीमों को साझा शब्दावली देते हैं। “Strategy” या “Repository” कहने से एक लंबा विवरण संकुचित हो जाता है, जो रिव्यूज़ को तेज़ बनाता है और गलतफहमियाँ घटाता है।
पैटर्न सिस्टम व्यवहार को अधिक प्रत्याश्यशील बनाते हैं। एक परिचित पैटर्न यह उम्मीद सेट करता है कि लॉजिक कहाँ रहेगी, ऑब्जेक्ट्स कैसे सहयोग करेंगे, और किन बदलावों के असर फैलने की संभावना है। यह उत्पादन में कम सरप्राइज़ और नए सदस्यों के लिए कम "यह कैसे काम करता है?" क्षण लाता है।
नाकामी का तरीका कार्गो-कल्टिंग है: किसी पैटर्न को इसलिए लागू करना क्योंकि वह लोकप्रिय है, किसी किताब में सूचीबद्ध है, या “यही यहाँ करते हैं।” इससे अक्सर ओवर-इंजीनियरिंग होती है—अतिरिक्त लेयर्स, इंडिरेक्शन, और ऐसे एब्स्ट्रैक्शन्स जो उपयोगिता नहीं देते।
एक और आम जाल है “हर चीज़ के लिए पैटर्न।” जब हर छोटी समस्या को एक नामी हल मिल जाता है, तो कोडबेस एक चतुराई के संग्रहालय में बदल सकता है न कि शिपिंग और मेंटेनेंस का उपकरण।
समस्या से शुरू करें, पैटर्न से नहीं।
पुछिए:
फिर उस सबसे सरल पैटर्न को चुनें जो फिट बैठे और विकल्प खुला रखे। अगर बाद में डिज़ाइन में और संरचना चाहिए तो आप उसे क्रमशः जोड़ सकते हैं—अक्सर असली दर्द के द्वारा और रिफैक्टरिंग से, न कि अनुमान लगाकर पहले से।
रिफैक्टरिंग सॉफ़्टवेयर के आंतरिक डिज़ाइन को बेहतर करने की वह प्रैक्टिस है जिसमें फ़ंक्शनल्टी नहीं बदलती। उपयोगकर्ता को रिफैक्टरिंग के बाद कुछ अलग महसूस नहीं करना चाहिए—सिवाय इसके कि भविष्य के बदलाव आसान, सुरक्षित और तेज़ हो जाएँ।
मार्टिन फाउलर का उद्देश्य सिर्फ “कोड सुन्दर रखें” नहीं है। उनका विचार है कि आर्किटेक्चर कोई एक-बार की डायग्राम नहीं है। आर्किटेक्चर वे फैसले हैं जो तय करते हैं कि सिस्टम कितना आसानी से बदलेगा। रिफैक्टरिंग उन निर्णयों को कठोर बन्धनों में बदलने से रोकने का तरीका है।
समय के साथ, भले डिज़ाइन वाले सिस्टम भी बहक जाते हैं। नई फीचर्स समय दबाव में जोड़ी जाती हैं, त्वरित फिक्स स्थायी बन जाते हैं, और सीमाएँ धुंधली हो जाती हैं। रिफैक्टरिंग स्पष्ट पृथक्करण बहाल करने और आकस्मिक जटिलता घटाने का तरीका है ताकि सिस्टम बदलने योग्य बना रहे।
एक स्वस्थ आर्किटेक्चर वह है जहाँ:
रिफैक्टरिंग रोज़मर्रा का काम है जो इन गुणों को बरकरार रखता है।
आप आमतौर पर रिफैक्टरिंग शेड्यूल नहीं करते क्योंकि कैलेंडर रिमाइंडर आया हो। आप इसे तब करते हैं जब कोड विरोध करने लगता है:
जब ये दिखें, आर्किटेक्चर पहले ही प्रभावित हो रहा है—रिफैक्टरिंग मरम्मत है।
सुरक्षित रिफैक्टरिंग कुछ आदतों पर निर्भर करती है:
इस तरह किया जाए तो रिफैक्टरिंग नियमित रख-रखाव बन जाती है—सिस्टम को अगले बदलाव के लिए तैयार रखना, पिछले के बाद नाज़ुक नहीं बनने देना।
टेक्निकल डेट आज के शॉर्टकट्स से बनने वाली भविष्य की लागत है। यह “खराब कोड” नहीं है किसी नैतिक विफलता के रूप में; यह एक ट्रेडऑफ है (कभी-कभी जानकर किया गया) जो बाद में बदलने की कीमत बढ़ाता है। फाउलर का फ्रेम उपयोगी है: डेट तब ही समस्या बनती है जब आप उसे ट्रैक करना बंद कर देते हैं और मानते हैं कि वह मौजूद नहीं है।
जानबूझकर डेट आंखें खोल कर लिया जाता है: “हम अभी सरल वर्जन शिप करेंगे, फिर अगली स्प्रिंट में इसे हार्डन करेंगे।” यह तर्कसंगत हो सकता है—अगर आप इसे चुकाने का भी प्लान रखते हैं।
दुर्घटनावश डेट तब बनती है जब टीम को नहीं पता कि वे उधार ले रहे हैं: गंदी निर्भरताएँ फैल जाती हैं, अस्पष्ट डोमेन मॉडल फैलता है, या त्वरित वर्कअराउंड डिफ़ॉल्ट बन जाता है। दुर्घटनावश डेट अक्सर ज़्यादा महँगी होती है क्योंकि किसी की भी मालिकाना भावना नहीं होती।
डेट सामान्य दबावों से जमा होता है:
परिणाम अनुमानित है: फीचर्स धीमे होते हैं, बग बढ़ते हैं, और रिफैक्टरिंग जोखिम भरी लगने लगती है।
आपको बड़े प्रोग्राम की ज़रूरत नहीं है ताकि डेट चुकाने की शुरुआत हो:
अगर आप डेट-संबंधी निर्णय भी दिखाते हैं (देखें /blog/architecture-decision-records), तो आप छिपे हुए खर्चों को मैनेजबल काम में बदल देते हैं।
सॉफ़्टवेयर आर्किटेक्चर कोई ब्लूप्रिंट नहीं है जिसे आप एक बार "सही" कर लें। फाउलर का दृष्टिकोण एक व्यावहारिक विचार की ओर तियार करता है: मान लें कि आवश्यकताएँ, ट्रैफ़िक, टीमें, और बाधाएँ बदलेंगी—फिर ऐसा डिज़ाइन करें कि सिस्टम बिना दर्दनाक रीराइट के अनुकूल हो सके।
एवोल्यूशनरी आर्किटेक्चर का मतलब है बदलाव के लिए डिज़ाइन करना, परफेक्शन के लिए नहीं। “हम माइक्रोसर्विसेस चाहिएँगे” या “हम 100x स्केल करेंगे” जैसी लंबी अवधि की शर्तों पर दांव लगाने की बजाय आप ऐसा आर्किटेक्चर बनाते हैं जो सुरक्षित रूप से विकसित हो: स्पष्ट सीमाएँ, ऑटोमेटेड टेस्ट, और डिप्लॉयमेंट प्रथाएँ जो बार-बार, कम-जोखिम वाले समायोजन की अनुमति दें।
योजनाएँ अनुमान हैं; प्रोडक्शन वास्तविकता है। छोटे increments रिलीज़ करने से आप सीखते हैं कि उपयोगकर्ता वास्तव में क्या करते हैं, सिस्टम का ऑपरेटिंग लागत क्या है, और प्रदर्शन या विश्वसनीयता कहाँ वाकई मायने रखती है।
छोटे रिलीज़ निर्णय शैली को बदल देते हैं: आप एक मामूली सुधार आज़मा सकते हैं (जैसे एक मॉड्यूल को अलग करना या नया API वर्ज़न लाना) और माप सकते हैं कि क्या फायदा हुआ—बड़े माइग्रेशन पर कमिट किए बिना।
यहाँ तेज़ इटरेशन टूल मदद कर सकते हैं—जब तक आप आर्किटेक्चरल गार्डरैलों को बनाए रखते हैं। उदाहरण के लिए, अगर आप Koder.ai जैसे प्लेटफ़ॉर्म का उपयोग करके फीचर्स जल्दी जेनरेट और इटरेट करते हैं, तो उस गति को स्थिर मॉड्यूल बॉउंड्रीज़, अच्छे टेस्ट और बार-बार डिप्लॉयमेंट के साथ जोड़ना आपको "तेज़ शिप कर के खुद को कोने में फंसा देने" से बचाएगा।
एक प्रमुख विकासवादी विचार है “फिटनेस फंक्शन”: एक मापनीय चेक जो एक आर्किटेक्चरल लक्ष्य की रक्षा करता है। इसे गार्डरैज की तरह सोचिए। अगर गार्डरैज ऑटोमेटेड है और लगातार चलता है, तो आप भरोसे के साथ सिस्टम बदल सकते हैं क्योंकि गार्डरैस जब भी आप रास्ते से भटकते हैं तो चेतावनी देंगे।
फिटनेस फंक्शन्स को भव्य बनाने की ज़रूरत नहीं है। वे सरल मीट्रिक्स, टेस्ट्स, या थ्रेशोल्ड्स हो सकते हैं जो आप परवाह करते हैं।
मकसद सब कुछ मापना नहीं है; कुछ ऐसे चेक चुनना है जो आपकी आर्किटेक्चरल वादों—बदलाव की रफ्तार, विश्वसनीयता, सुरक्षा, अंतर-कार्यशीलता—को दर्शाएँ और उन्हें रोज़मर्रा के निर्णयों से मार्गदर्शित करने दें।
माइक्रोसर्विसेस इंजीनियरिंग परिपक्वता का बैज नहीं हैं। फाउलर का बिंदु सरल है: सिस्टम को सर्विसेस में बाँटना उतना ही संगठनात्मक कदम है जितना तकनीकी। अगर आपकी टीमें सर्विसेज़ को एंड-टू-एंड (बनाना, डिप्लॉय करना, ऑपरेट करना, और विकसित करना) नहीं संभाल सकतीं, तो आपको लाभ के बिना जटिलता मिल जाएगी।
एक मोनोलिथ एक डिप्लॉयेबल यूनिट है। यह ताकत हो सकती है: कम चलती चीज़ें, सरल डिबगिंग, और स्पष्ट डेटा कंसिस्टेंसी। नुकसान तब दिखता है जब कोडबेस उलझ जाता है—छोटे बदलाव बड़े समन्वय माँगते हैं।
एक मॉड्यूलर मोनोलिथ अभी भी एक डिप्लॉयेबल यूनिट है, पर कोड जानबूझकर स्पष्ट मॉड्यूल्स में विभाजित है। आप मोनोलिथ की ऑपरेशनल सरलता रखते हैं जबकि आंतरिक कपलिंग घटती है। कई टीमों के लिए यह सबसे अच्छा डिफ़ॉल्ट है।
माइक्रोसर्विसेस हर सर्विस को अपनी डिप्लॉयमेंट और लाइफसाइकल देती हैं। यह तेज़ स्वतंत्र रिलीज़ और स्पष्ट स्वामित्व खोल सकती हैं—अगर संगठन इसके लिए तैयार हो। अन्यथा, यह अक्सर “एक कठिन समस्या” को “दस कठिन समस्याओं” में बदल देता है।
माइक्रोसर्विसेस वह ओवरहेड जोड़ते हैं जो आर्किटेक्चर डायग्राम पर दिखाई नहीं देता:
एक मॉड्यूलर मोनोलिथ से शुरू करें। वास्तविक दबाव मापें: रिलीज़ बॉटलनेक्स, किसी मॉड्यूल के आसपास टीम टकराव, स्केलिंग हॉटस्पॉट्स, या विश्वसनीयता अलगाव की ज़रूरतें। जब वे दबाव लगातार और मापे गए हों, तो एक स्पष्ट बॉउंड्री के साथ एक सर्विस निकाले—समर्पित स्वामित्व और ऑपरेशन की योजना के साथ, सिर्फ़ कोड नहीं।
अच्छा आर्किटेक्चर यह नहीं है कि आपके पास कितनी सर्विसेज़ हैं; यह है कि आप एक हिस्से को कितनी अच्छी तरह बदल सकते हैं बिना तीन और हिस्सों को आकस्मिक रूप से तोड़े। मार्टिन फाउलर अक्सर इसे कपलिंग (किस हद तक हिस्से उलझे हुए हैं) और कोहेज़न (किस हद तक एक हिस्सा अपने काम के साथ समझदार रूप से जुड़ा है) के रूप में फ्रेम करते हैं।
एक रेस्टोरेंट किचन की कल्पना कीजिए। एक कोहेसिव स्टेशन (जैसे “सलाद”) के पास सब कुछ होता है—सामग्री, उपकरण, और स्पष्ट जिम्मेदारी। एक टाइटली कपल्ड किचन वह है जहाँ सलाद बनाने के लिए ग्रिल कुक को रोकना पड़े, पेस्ट्री शेफ को ड्रेसिंग की मंज़ूरी देनी पड़े, और मैनेजर को फ्रिज अनलॉक करना पड़े।
सॉफ्टवेयर भी ऐसा ही काम करता है: कोहेसिव मॉड्यूल्स का एक स्पष्ट काम होता है; ढीले कपल्ड मॉड्यूल्स सरल, स्थिर समझौतों के माध्यम से इंटरैक्ट करते हैं।
अस्वस्थ कपलिंग आमतौर पर कोड से पहले शेड्यूल में दिखती है। सामान्य संकेत:
अगर आपकी डिलीवरी प्रक्रिया नियमित रूप से समूह समन्वय मांगती है, तो निर्भरता लागत पहले से ही चुकाई जा रही है—बस मीटिंग्स और देरी के रूप में।
कपलिंग घटाने के लिए रीराइट की ज़रूरत नहीं है। व्यावहारिक कदमों में शामिल हैं:
जब निर्णय महत्वपूर्ण हों, तो उन्हें हल्के नोट्स जैसे /blog/architecture-decision-records में कैप्चर करें ताकि सीमाएँ जानबूझकर बनी रहें।
शेयर्ड डेटाबेस “गुप्त” कपलिंग बनाते हैं: कोई भी टीम कोई टेबल बदल सकती है और अनजाने में दूसरों को तोड़ सकती है। साझा DB अक्सर समन्वित रिलीज़ को मजबूर करता है, भले ही सर्विसेज़ अलग दिखती हों।
स्वस्थ तरीका है डेटा ओनरशिप: एक सिस्टम किसी dataset का मालिक हो और उसे API या इवेंट्स के जरिए एक्स्पोज़ करे। इससे निर्भरताएँ दृश्यमान बनती हैं—और इसलिए मैनेजेबल भी।
सॉफ़्टवेयर आर्किटेक्चर सिर्फ़ बॉक्स-और-ऐरो नहीं है। यह लोगों के बारे में भी है: काम कैसे बाँटा जाता है, निर्णय कैसे लिए जाते हैं, और जब वास्तविकता डिज़ाइन से असहमत हो तो टीम कितनी तेज़ प्रतिक्रिया दे सकती है। यह सोशियो-टेक्निकल आर्किटेक्चर है—विचार कि सिस्टम की संरचना आपकी टीम संरचना को प्रतिबिंबित करती है।
एक आम फेल्यर मोड यह है कि पेपर पर “साफ” सीमाएँ डिज़ाइन की जाती हैं जबकि रोज़मर्रा का वर्कफ्लो उन सीमाओं को काटता है। सिस्टम तकनीकी रूप से कंपाइल और डिप्लॉय हो सकता है, पर बदलना महँगा महसूस होता है।
मेल-मेल के संकेत:
मालिकाना से शुरू करें, परफेक्ट से नहीं। उन सीमाओं का लक्ष्य रखें जो आपकी टीमें व्यवहारिक रूप से संचालित कर सकें।
कभी-कभी आप टीमें पुनर्गठित नहीं कर सकते, कोई लेगेसी मॉड्यूल नहीं बाँट सकते, या बोतलबैक को हल करने के लिए हायर नहीं कर सकते। उन मामलों में, आर्किटेक्चर को एक बातचीत के रूप में देखें: उन सीमाओं को चुनें जो सबसे महँगे समन्वय को घटाते हैं, उन रिफैक्टरिंग में निवेश करें जो स्वतंत्रता खोलते हैं, और संक्रमणकालीन समझौते स्वीकार करें जब तक आप टेक्निकल और संगठनात्मक डेट चुकाते हैं।
सॉफ़्टवेयर आर्किटेक्चर सिर्फ वही नहीं जो आप बनाते हैं—यह उन निर्णयों के बारे में भी है जो आप रास्ते में लेते हैं। आर्किटेक्चर डिसीजन रिकॉर्ड्स (ADRs) छोटे नोट्स होते हैं जो उन निर्णयों को तब कैद करते हैं जब संदर्भ अभी ताज़ा होता है।
ADR एक एक-पेज मेमो है जो जवाब देता है: “हमने क्या फैसला किया, और क्यों?” यह लंबा डिज़ाइन डॉक्यूमेंट नहीं है, और न ही परमिशन स्लिप। इसे टीम की एक टिकाऊ याद के रूप में सोचें।
ढाँचा लगातार रखें ताकि लोग जल्दी स्कैन कर सकें। एक हल्का ADR आम तौर पर शामिल करता है:
ADRs ऑनबोर्डिंग तेज़ करते हैं क्योंकि नए साथी किन्तु केवल अंतिम परिणाम नहीं बल्कि तर्क भी पढ़ सकते हैं। वे बार-बार बहसों को रोकते हैं: जब वही प्रश्न महीनों बाद लौटता है, आप ADR को पुनः देख सकते हैं और उसे अपडेट कर सकते हैं बजाय फिर से वही बहस करने के। सबसे महत्वपूर्ण बात, ADRs ट्रेड-ऑफ को स्पष्ट बनाते हैं—जब वास्तविकता बदले और आपको योजना संशोधित करनी पड़े तो यह उपयोगी होता है।
एक सरल टेम्पलेट का उपयोग करें, ADRs को कोड के पास सेव करें (उदाहरण के लिए, /docs/adr/), और एक ADR लिखने में 10–20 मिनट का लक्ष्य रखें।
# ADR 012: API versioning strategy
Date: 2025-12-26
Status: Accepted
Owners: Platform team
Context:
We need to evolve public APIs without breaking partners.
Decision:
Adopt URL-based versioning (/v1/, /v2/).
Alternatives:
- Header-based versioning
- No versioning; rely on backward compatibility
Consequences:
+ Clear routing and documentation
- More endpoints to support over time
अगर कोई ADR कागज़ात जैसा लगे, तो उसे छोटा करें—आदत को न छोड़ें।
आर्किटेक्चर "अच्छा" तब रहता है जब सिस्टम छोटे कदमों में, वास्तविक दुनिया के दबाव के तहत सुरक्षित रूप से बदल सकता है। इसलिए कंटीन्युअस डिलीवरी (CD) और तेज़ फीडबैक लूप इतने महत्वपूर्ण हैं: वे विकास को एक जोखिम भरे आयोजन की जगह सामान्य आदत बना देते हैं।
रिफैक्टरिंग सबसे आसान तब है जब बदलाव छोटे और पलटने योग्य हों। एक स्वस्थ CI/CD पाइपलाइन हर बदलाव का ऑटोमेटेड बिल्ड, टेस्ट, और वेलिडेशन करके इसका समर्थन करती है। जब पाइपलाइन भरोसेमंद होती है, टीमें निरंतर डिज़ाइन बेहतर कर सकती हैं बजाय किसी "बड़े रीराइट" का इंतज़ार करने के जो कभी शिप न हो।
क्वालिटी गेट्स तेज़, सुसंगत और उन परिणामों से जुड़े होने चाहिए जिनकी आप परवाह करते हैं। सामान्य गेट्स में शामिल हैं:
मकसद परफेक्शन नहीं है; तोड़ने वाले बदलाव की लागत बढ़ाना और सुरक्षित सुधारों की लागत घटाना है।
अच्छा आर्किटेक्चर आंशिक रूप से यह जानने के बारे में भी है कि प्रोडक्शन में सिस्टम क्या कर रहा है। बिना फीडबैक के आप अनुमान पर ऑप्टिमाइज़ कर रहे होते हैं।
जब ये संकेत मौजूद हों, आप आर्किटेक्चरल निर्णयों को गवाहियों से सत्यापित कर सकते हैं, रायों से नहीं।
विकास के लिए बदलते रहना आवश्यक है, इसलिए आपको एस्केप हैच चाहिए। फीचर फ्लैग्स डिप्लॉय से रिलीज़ को अलग करते हैं। कैनरी रिलीज़ ब्लास्ट रेडियस को सीमित करते हैं। स्पष्ट रोलबैक रणनीति (डेटाबेस विचारों सहित) विफलताओं को रिकवर करने योग्य घटनाओं में बदल देती है।
अगर आपका एप्लिकेशन प्लेटफ़ॉर्म स्नैपशॉट्स और रोलबैक सपोर्ट करता है (उदाहरण के लिए, Koder.ai), तो आप यही सिद्धांत प्रोडक्ट-डिलीवरी लेयर पर भी लागू कर सकते हैं: तेज़ी से मूव करें, पर पलटने योग्य और ऑपरेशनल सुरक्षा को डिफ़ॉल्ट रखें।
CI/CD और फीडबैक मिलकर एक ऐसा सिस्टम बनाते हैं जो लगातार विकसित हो सकता है—बिल्कुल वही प्रकार की आर्किटेक्चर जो ट्रेंड्स से आगे टिकती है।
आपको बेहतर आर्किटेक्चर के लिए रीराइट की ज़रूरत नहीं। आपको कुछ दोहराने योग्य आदतें चाहिए जो डिज़ाइन समस्याओं को दृश्यमान, पलटने योग्य, और लगातार बेहतर बनाएँ।
अगले 30 दिन: एक "हॉट स्पॉट" चुनें (उच्च-चेंज, बार-बार इन्सिडेंट वाला)। एक कैरक्टराइज़ेशन टेस्ट सूट जोड़ें, एक निर्भरता चेन सरल बनाइए, और नए परिवर्तनों के लिए हल्के निर्णय नोट लिखना शुरू करें।
60 दिनों तक: एक समस्या वाली सीम को रिफैक्टर करें: एक मॉड्यूल निकालें, इंटरफ़ेस परिभाषित करें, या परसिस्टेंस/मैसेजिंग जैसे इन्फ्रा चिंताओं को बॉउंड्री के पीछे अलग करें। बदलाव के ब्लास्ट रेडियस को घटाएँ।
90 दिनों तक: अपनी डिलीवरी लूप सुधारें। छोटे पुल रिक्वेस्ट्स, तेज़ बिल्ड्स, और एक पूर्वानुमानित रिलीज़ कैडेंस का लक्ष्य रखें। यदि आप माइक्रोसर्विसेस पर विचार कर रहे हैं, तो पहले यह साबित करें कि एक बॉउंड्री मौजूदा कोडबेस के अंदर मैनेज नहीं की जा सकती।
(अगर आपका लक्ष्य बस अधिक प्रोडक्ट बिना हैंडऑफ़ के शिप करना है, तो देखिए कि ऑटोमेशन कहाँ मदद कर सकता है। कुछ टीमों के लिए चैट-ड्रिवन बिल्ड वर्कफ़्लो जैसे Koder.ai—प्लानिंग मोड, स्रोत एक्सपोर्ट, डिप्लॉयमेंट/होस्टिंग, कस्टम डोमेन, और मुफ्त से एंटरप्राइज़ तक की टियरड प्राइसिंग—मेकैनिकल ओवरहेड घटा सकते हैं जबकि आप आर्किटेक्चरल ध्यान सीमाओं, टेस्ट्स, और ऑपरेशनल फीडबैक पर केंद्रित रखें)।
कुछ संकेत मासिक ट्रैक करें:
यदि ये सुधार नहीं कर रहे, तो योजना समायोजित करें—आर्किटेक्चर तभी "बेहतर" होता है जब वह बदलाव को सुरक्षित और सस्ता बनाता है।
स्टैक्स बदलते रहेंगे। मूल बातें—स्पष्ट सीमाएँ, रिफैक्टरिंग अनुशासन, और तेज़ फीडबैक—स्थायी रहती हैं।
आर्किटेक्चर उन फैसलों का समूह है जिन्हें बाद में बदलना महंगा और कठिन होता है: सीमाएँ, डेटा की जिम्मेदारी, इंटीग्रेशन स्टाइल और फेलियर हैंडलिंग।
टेक स्टैक वे टूल होते हैं जिनसे आप उन फैसलों को लागू करते हैं (फ्रेमवर्क, लाइब्रेरीज़, क्लाउड प्रोडक्ट्स)। बहुत से टूल आसानी से बदले जा सकते हैं; लेकिन सीमाओं या डेटा फ्लो को बदलना अक्सर हफ्तों का समन्वय मांगता है।
एक अच्छा परीक्षण उलटibility है: अगर किसी फैसले को वापस लेने में हफ्तों लगेंगे और कई टीमों का समन्वय चाहिए होगा, तो वह आर्किटेक्चरल है।
उदाहरण:
पैटर्न का उपयोग तब करें जब वह किसी बार-बार आने वाली समस्या का स्पष्ट, सादा हल दे रहा हो—not सिर्फ ताकि डिज़ाइन प्रोफेशनल लगे।
त्वरित चयन चेकलिस्ट:
अगर आप समस्या को स्पष्ट रूप से नहीं बता सकते, तो अभी पैटर्न न जोड़ें।
रिफैक्टरिंग को सामान्य मेंटेनेंस की तरह देखें, न कि सिर्फ ‘कोड सुंदर रखने’ की गतिविधि।
सामान्य ट्रिगर्स:
सुरक्षित रखने के लिए: टेस्ट, छोटे-छोटे कदम, और कड़ा कोड रिव्यू स्कोप अपनाएँ।
ऋण को एक लागत के रूप में ट्रैक करें, किसी की नैतिक विफलता के रूप में नहीं।
व्यावहारिक तरीके:
निर्णय स्पष्ट रखें (उदाहरण के लिए, हल्के ADRs के साथ)।
यह मतलब है कि आप ऐसे तरीके बनाते हैं जिनसे सीखते हुए दिशा सुरक्षित रूप से बदली जा सके—ना कि लंबी अवधि की भविष्यवाणी पर सब कुछ दांव लगाना।
आम घटक:
लक्ष्य अनुकूलनीयता है, न कि आदर्श प्रारूप।
फिटनेस फ़ंक्शन वह ऑटोमेटेड गार्ड रेल है जो किसी आर्किटेक्चरल लक्ष्य की रक्षा करता है।
उपयोगी उदाहरण:
कुछ ऐसे ही चुने जो आपकी वादों (बदलाव की रफ़्तार, विश्वसनीयता, सुरक्षा) को दर्शाएँ और उन्हें लगातार चलाएँ।
डिफ़ॉल्ट के रूप में मॉड्यूलर मोनोलिथ से शुरू करें जब तक कि आपके पास मापी गयी, लगातार दबाव न हो जो स्वतंत्र डिप्लॉयेबिलिटी मांगता हो।
माइक्रोसर्विसेस तब फायदेमंद होते हैं जब:
अगर आप एक सर्विस को प्रोडक्शन में आराम से नहीं चला सकते, तो दस में विभाजन अक्सर दर्द को बढ़ा देता है।
निर्भरता को दृश्यमान और इरादतन बनाकर शुरू करें।
उच्च-प्रभावी कदम:
शेयर्ड DB “गुप्त” कपलिंग बनाती है और समन्वित रिलीज़ को मजबूर करती है—even अगर सिस्टम अलग दिखते हों।
ADRs इसलिए लिखें ताकि आप यह रिकॉर्ड कर सकें कि आपने क्या निर्णय लिया और क्यों, जब संदर्भ अभी ताजा हो।
हल्का ADR शामिल करता है:
इन्हें कोड के पास रखें (उदाहरण: ) और संबंधित गाइडेंस जैसे से लिंक करें।
/docs/adr/