प्रणाली
निम्नलिखित आमतौर पर एक प्रणाली की वांछनीय विशेषताएं हैं:- न्यूनतम जटिलता। अत्यधिक जटिल परियोजनाओं से बचना चाहिए। सबसे महत्वपूर्ण बात सरलता और स्पष्टता है (सरल = बेहतर)।
- रखरखाव में आसानी। एप्लिकेशन बनाते समय, आपको याद रखना चाहिए कि इसे बनाए रखने की आवश्यकता होगी (भले ही आप व्यक्तिगत रूप से इसे बनाए रखने के लिए ज़िम्मेदार न हों)। इसका मतलब है कि कोड स्पष्ट और स्पष्ट होना चाहिए।
- लूस कपलिंग। इसका मतलब यह है कि हम कार्यक्रम के विभिन्न भागों के बीच निर्भरताओं की संख्या को कम करते हैं (ओओपी सिद्धांतों के साथ हमारे अनुपालन को अधिकतम करते हैं)।
- पुन: प्रयोज्य। हम अपने सिस्टम को अन्य अनुप्रयोगों में घटकों का पुन: उपयोग करने की क्षमता के साथ डिज़ाइन करते हैं।
- सुवाह्यता। एक प्रणाली को दूसरे वातावरण में अनुकूलित करना आसान होना चाहिए।
- वर्दी शैली। हम अपने सिस्टम को इसके विभिन्न घटकों में एक समान शैली का उपयोग करके डिज़ाइन करते हैं।
- एक्स्टेंसिबिलिटी (स्केलेबिलिटी)। हम इसकी मूल संरचना का उल्लंघन किए बिना सिस्टम को बढ़ा सकते हैं (एक घटक को जोड़ना या बदलना अन्य सभी को प्रभावित नहीं करना चाहिए)।
एक प्रणाली को डिजाइन करने के चरण
- सॉफ्टवेयर सिस्टम। एप्लिकेशन को समग्र रूप से डिज़ाइन करें।
- सबसिस्टम/पैकेज में विभाजन। तार्किक रूप से अलग-अलग हिस्सों को परिभाषित करें और उनके बीच बातचीत के नियमों को परिभाषित करें।
- सबसिस्टम का वर्गों में विभाजन। सिस्टम के कुछ हिस्सों को विशिष्ट वर्गों और इंटरफेस में विभाजित करें, और उनके बीच की बातचीत को परिभाषित करें।
- विधियों में वर्गों का विभाजन। किसी वर्ग को सौंपे गए उत्तरदायित्व के आधार पर उसके लिए आवश्यक विधियों की पूरी परिभाषा तैयार करें।
- विधि डिजाइन। व्यक्तिगत तरीकों की कार्यक्षमता की एक विस्तृत परिभाषा बनाएँ।
सिस्टम डिजाइन के सामान्य सिद्धांत और अवधारणाएं
आलसी आरंभीकरण। इस प्रोग्रामिंग मुहावरे में, एप्लिकेशन ऑब्जेक्ट बनाने में समय बर्बाद नहीं करता है जब तक कि इसका वास्तव में उपयोग नहीं किया जाता है। यह प्रारंभिक प्रक्रिया को गति देता है और कचरा संग्राहक पर भार कम करता है। उस ने कहा, आपको इसे बहुत दूर नहीं ले जाना चाहिए, क्योंकि यह प्रतिरूपकता के सिद्धांत का उल्लंघन कर सकता है। शायद यह निर्माण के सभी उदाहरणों को किसी विशिष्ट भाग में ले जाने के लायक है, उदाहरण के लिए, मुख्य विधि या फ़ैक्टरी वर्ग के लिए। अच्छे कोड की एक विशेषता दोहराए जाने वाले बॉयलरप्लेट कोड का अभाव है। एक नियम के रूप में, ऐसे कोड को एक अलग वर्ग में रखा जाता है ताकि जरूरत पड़ने पर उसे बुलाया जा सके।एओपी
मैं पहलू-उन्मुख प्रोग्रामिंग पर भी ध्यान देना चाहूंगा। यह प्रोग्रामिंग प्रतिमान पारदर्शी तर्क पेश करने के बारे में है। यही है, दोहराए जाने वाले कोड को कक्षाओं (पहलुओं) में रखा जाता है और कुछ शर्तों के पूरा होने पर इसे कॉल किया जाता है। उदाहरण के लिए, किसी विशिष्ट नाम के साथ किसी विधि को कॉल करते समय या किसी विशिष्ट प्रकार के चर को एक्सेस करते समय। कभी-कभी पहलू भ्रामक हो सकते हैं, क्योंकि यह तुरंत स्पष्ट नहीं होता है कि कोड कहाँ से कहा जा रहा है, लेकिन यह अभी भी बहुत उपयोगी कार्यक्षमता है। खासकर जब कैशिंग या लॉगिंग। हम सामान्य कक्षाओं में अतिरिक्त तर्क जोड़े बिना इस कार्यक्षमता को जोड़ते हैं। एक साधारण वास्तुकला के लिए केंट बेक के चार नियम:- अभिव्यक्ति - एक वर्ग का इरादा स्पष्ट रूप से व्यक्त किया जाना चाहिए। यह उचित नामकरण, छोटे आकार और एकल-जिम्मेदारी सिद्धांत के पालन के माध्यम से प्राप्त किया जाता है (जिस पर हम नीचे और अधिक विस्तार से विचार करेंगे)।
- कक्षाओं और विधियों की न्यूनतम संख्या - कक्षाओं को जितना संभव हो उतना छोटा और संकीर्ण रूप से केंद्रित बनाने की आपकी इच्छा में, आप बहुत दूर जा सकते हैं (जिसके परिणामस्वरूप शॉटगन सर्जरी विरोधी पैटर्न होती है)। यह सिद्धांत सिस्टम को कॉम्पैक्ट रखने और बहुत दूर नहीं जाने, हर संभव कार्रवाई के लिए एक अलग वर्ग बनाने का आह्वान करता है।
- कोई डुप्लीकेशन नहीं - डुप्लीकेट कोड, जो भ्रम पैदा करता है और सबइप्टिमल सिस्टम डिज़ाइन का संकेत है, निकाला जाता है और एक अलग स्थान पर ले जाया जाता है।
- सभी परीक्षण चलाता है - एक प्रणाली जो सभी परीक्षणों को पास करती है वह प्रबंधनीय है। किसी भी परिवर्तन के कारण परीक्षण विफल हो सकता है, जिससे हमें पता चलता है कि किसी पद्धति के आंतरिक तर्क में हमारे परिवर्तन ने सिस्टम के व्यवहार को भी अप्रत्याशित तरीके से बदल दिया।
ठोस
सिस्टम डिजाइन करते समय, जाने-माने SOLID सिद्धांत विचार करने योग्य हैं:एस (एकल जिम्मेदारी), ओ (ओपन-क्लोज्ड), एल (लिस्कोव प्रतिस्थापन), आई (इंटरफ़ेस अलगाव), डी (निर्भरता व्युत्क्रम)।
हम प्रत्येक व्यक्तिगत सिद्धांत पर ध्यान नहीं देंगे। यह इस लेख के दायरे से थोड़ा परे होगा, लेकिन आप यहां और अधिक पढ़ सकते हैं ।इंटरफेस
शायद एक अच्छी तरह से डिज़ाइन की गई कक्षा बनाने में सबसे महत्वपूर्ण चरणों में से एक एक अच्छी तरह से डिज़ाइन किया गया इंटरफ़ेस बनाना है जो एक अच्छा अमूर्तता का प्रतिनिधित्व करता है, कक्षा के कार्यान्वयन विवरण को छुपाता है और साथ ही एक दूसरे के साथ स्पष्ट रूप से संगत विधियों का एक समूह प्रस्तुत करता है। आइए SOLID सिद्धांतों में से एक पर करीब से नज़र डालें - इंटरफ़ेस पृथक्करण: ग्राहकों (वर्गों) को अनावश्यक तरीकों को लागू नहीं करना चाहिए जिनका वे उपयोग नहीं करेंगे। दूसरे शब्दों में, यदि हम इंटरफ़ेस की एकमात्र नौकरी करने के उद्देश्य से कम से कम विधियों के साथ एक इंटरफ़ेस बनाने के बारे में बात कर रहे हैं (जो मुझे लगता है कि एकल जिम्मेदारी सिद्धांत के समान ही है), इसके बजाय कुछ छोटे बनाना बेहतर है एक फूला हुआ इंटरफ़ेस। सौभाग्य से, एक वर्ग एक से अधिक इंटरफ़ेस लागू कर सकता है। अपने इंटरफेस को ठीक से नाम देना याद रखें: नाम को असाइन किए गए कार्य को यथासंभव सटीक रूप से प्रतिबिंबित करना चाहिए। और, ज़ाहिर है, यह जितना छोटा होगा, उतना ही कम भ्रम पैदा करेगा। दस्तावेज़ीकरण टिप्पणियाँ आमतौर पर इंटरफ़ेस स्तर पर लिखी जाती हैं। ये टिप्पणियाँ इस बारे में विवरण प्रदान करती हैं कि प्रत्येक विधि को क्या करना चाहिए, इसके लिए क्या तर्क चाहिए और यह क्या लौटाएगा।कक्षा
- सार्वजनिक स्थैतिक स्थिरांक;
- निजी स्थिर स्थिरांक;
- निजी उदाहरण चर।
क्लास साइज़
अब मैं कक्षाओं के आकार के बारे में बात करना चाहूंगा। आइए ठोस सिद्धांतों में से एक को याद करें - एकल उत्तरदायित्व सिद्धांत। इसमें कहा गया है कि प्रत्येक वस्तु का केवल एक उद्देश्य (जिम्मेदारी) होता है, और इसके सभी तरीकों का तर्क इसे पूरा करने का लक्ष्य रखता है। यह हमें बड़े, फूले हुए वर्गों (जो वास्तव में गॉड ऑब्जेक्ट एंटी-पैटर्न हैं) से बचने के लिए कहता है, और अगर हमारे पास एक वर्ग में सभी तरह के विभिन्न तर्कों के साथ बहुत सारे तरीके हैं, तो हमें इसे अलग करने के बारे में सोचने की जरूरत है। कुछ तार्किक भागों (वर्ग)। बदले में, यह कोड की पठनीयता में वृद्धि करेगा, क्योंकि यदि हम किसी दिए गए वर्ग के अनुमानित उद्देश्य को जानते हैं तो प्रत्येक विधि के उद्देश्य को समझने में अधिक समय नहीं लगेगा। इसके अलावा, वर्ग के नाम पर भी नज़र रखें, जो उसमें शामिल तर्क को दर्शाता है। उदाहरण के लिए, यदि हमारे पास एक वर्ग है जिसके नाम में 20+ शब्द हैं, हमें रिफैक्टरिंग के बारे में सोचने की जरूरत है। किसी भी स्वाभिमानी वर्ग में इतने आंतरिक चर नहीं होने चाहिए। वास्तव में, प्रत्येक विधि उनमें से एक या कुछ के साथ काम करती है, जिससे कक्षा के भीतर बहुत अधिक सामंजस्य होता है (जो बिल्कुल वैसा ही है जैसा होना चाहिए, क्योंकि वर्ग को एक एकीकृत संपूर्ण होना चाहिए)। नतीजतन, एक वर्ग के सामंजस्य में वृद्धि से वर्ग के आकार में कमी आती है, और निश्चित रूप से, वर्गों की संख्या बढ़ जाती है। यह कुछ लोगों के लिए कष्टप्रद है, क्योंकि यह देखने के लिए कि कोई विशिष्ट बड़ा कार्य कैसे काम करता है, आपको कक्षा फ़ाइलों के बारे में अधिक जानने की आवश्यकता है। इन सबसे ऊपर, प्रत्येक वर्ग एक छोटा मॉड्यूल है जो दूसरों से न्यूनतम रूप से संबंधित होना चाहिए। यह अलगाव उन परिवर्तनों की संख्या को कम करता है जो हमें कक्षा में अतिरिक्त तर्क जोड़ते समय करने की आवश्यकता होती है। प्रत्येक विधि उनमें से एक या कुछ के साथ काम करती है, जिससे कक्षा के भीतर बहुत अधिक सामंजस्य होता है (जो बिल्कुल वैसा ही है जैसा कि होना चाहिए, क्योंकि वर्ग को एक एकीकृत संपूर्ण होना चाहिए)। नतीजतन, एक वर्ग के सामंजस्य में वृद्धि से वर्ग के आकार में कमी आती है, और निश्चित रूप से, वर्गों की संख्या बढ़ जाती है। यह कुछ लोगों के लिए कष्टप्रद है, क्योंकि यह देखने के लिए कि कोई विशिष्ट बड़ा कार्य कैसे काम करता है, आपको कक्षा फ़ाइलों के बारे में अधिक जानने की आवश्यकता है। इन सबसे ऊपर, प्रत्येक वर्ग एक छोटा मॉड्यूल है जो दूसरों से न्यूनतम रूप से संबंधित होना चाहिए। यह अलगाव उन परिवर्तनों की संख्या को कम करता है जो हमें कक्षा में अतिरिक्त तर्क जोड़ते समय करने की आवश्यकता होती है। प्रत्येक विधि उनमें से एक या कुछ के साथ काम करती है, जिससे कक्षा के भीतर बहुत अधिक सामंजस्य होता है (जो बिल्कुल वैसा ही है जैसा कि होना चाहिए, क्योंकि वर्ग को एक एकीकृत संपूर्ण होना चाहिए)। नतीजतन, एक वर्ग के सामंजस्य में वृद्धि से वर्ग के आकार में कमी आती है, और निश्चित रूप से, वर्गों की संख्या बढ़ जाती है। यह कुछ लोगों के लिए कष्टप्रद है, क्योंकि यह देखने के लिए कि कोई विशिष्ट बड़ा कार्य कैसे काम करता है, आपको कक्षा फ़ाइलों के बारे में अधिक जानने की आवश्यकता है। इन सबसे ऊपर, प्रत्येक वर्ग एक छोटा मॉड्यूल है जो दूसरों से न्यूनतम रूप से संबंधित होना चाहिए। यह अलगाव उन परिवर्तनों की संख्या को कम करता है जो हमें कक्षा में अतिरिक्त तर्क जोड़ते समय करने की आवश्यकता होती है। सामंजस्य वर्ग के आकार में कमी की ओर जाता है, और निश्चित रूप से, वर्गों की संख्या बढ़ जाती है। यह कुछ लोगों के लिए कष्टप्रद है, क्योंकि यह देखने के लिए कि कोई विशिष्ट बड़ा कार्य कैसे काम करता है, आपको कक्षा फ़ाइलों के बारे में अधिक जानने की आवश्यकता है। इन सबसे ऊपर, प्रत्येक वर्ग एक छोटा मॉड्यूल है जो दूसरों से न्यूनतम रूप से संबंधित होना चाहिए। यह अलगाव उन परिवर्तनों की संख्या को कम करता है जो हमें कक्षा में अतिरिक्त तर्क जोड़ते समय करने की आवश्यकता होती है। सामंजस्य वर्ग के आकार में कमी की ओर जाता है, और निश्चित रूप से, वर्गों की संख्या बढ़ जाती है। यह कुछ लोगों के लिए कष्टप्रद है, क्योंकि यह देखने के लिए कि कोई विशिष्ट बड़ा कार्य कैसे काम करता है, आपको कक्षा फ़ाइलों के बारे में अधिक जानने की आवश्यकता है। इन सबसे ऊपर, प्रत्येक वर्ग एक छोटा मॉड्यूल है जो दूसरों से न्यूनतम रूप से संबंधित होना चाहिए। यह अलगाव उन परिवर्तनों की संख्या को कम करता है जो हमें कक्षा में अतिरिक्त तर्क जोड़ते समय करने की आवश्यकता होती है।वस्तुओं
कैप्सूलीकरण
यहाँ हम पहले एक OOP सिद्धांत के बारे में बात करेंगे: एनकैप्सुलेशन। कार्यान्वयन को छिपाने के लिए चर को इन्सुलेट करने के लिए एक विधि बनाने की राशि नहीं है (व्यक्तिगत तरीकों, गेटर्स और सेटर्स के माध्यम से बिना सोचे समझे पहुंच को प्रतिबंधित करना, जो कि अच्छा नहीं है, क्योंकि एनकैप्सुलेशन का पूरा बिंदु खो गया है)। पहुंच को छिपाने का उद्देश्य अमूर्त बनाना है, अर्थात, वर्ग साझा ठोस तरीके प्रदान करता है जिसका उपयोग हम अपने डेटा के साथ काम करने के लिए करते हैं। और उपयोगकर्ता को यह जानने की आवश्यकता नहीं है कि हम इस डेटा के साथ कैसे काम कर रहे हैं — यह काम करता है और यह पर्याप्त है।डेमेटर का कानून
हम डेमेटर के नियम पर भी विचार कर सकते हैं: यह नियमों का एक छोटा समूह है जो वर्ग और विधि स्तर पर जटिलता को प्रबंधित करने में सहायता करता है। मान लीजिए कि हमारे पास कार ऑब्जेक्ट है, और इसमें एक मूव (ऑब्जेक्ट arg1, ऑब्जेक्ट arg2) विधि है। डेमेटर के नियम के अनुसार, यह विधि कॉल करने तक सीमित है:- कार ऑब्जेक्ट के तरीके (दूसरे शब्दों में, "यह" ऑब्जेक्ट);
- मूव मेथड के भीतर बनाई गई वस्तुओं के तरीके ;
- तर्कों के रूप में पारित वस्तुओं के तरीके ( arg1 , arg2 );
- आंतरिक कार वस्तुओं के तरीके (फिर से, "यह")।
डेटा संरचना
डेटा संरचना संबंधित तत्वों का एक संग्रह है। जब किसी वस्तु को डेटा संरचना के रूप में माना जाता है, तो डेटा तत्वों का एक सेट होता है, जिस पर विधियाँ संचालित होती हैं। इन विधियों का अस्तित्व निहित माना जाता है। अर्थात्, एक डेटा संरचना एक वस्तु है जिसका उद्देश्य संग्रहीत डेटा को संग्रहीत (प्रक्रिया) करना और उसके साथ काम करना है। एक नियमित वस्तु से इसका मुख्य अंतर यह है कि एक सामान्य वस्तु उन विधियों का एक संग्रह है जो डेटा तत्वों पर संचालित होती हैं जिन्हें निहित रूप से अस्तित्व में माना जाता है। क्या तुम समझ रहे हो? एक साधारण वस्तु का मुख्य पहलू विधियाँ हैं। आंतरिक चर उनके सही संचालन की सुविधा प्रदान करते हैं। लेकिन एक डेटा संरचना में, संग्रहीत डेटा तत्वों के साथ आपके काम का समर्थन करने के तरीके हैं, जो यहां सर्वोपरि हैं। एक प्रकार की डेटा संरचना डेटा ट्रांसफर ऑब्जेक्ट (डीटीओ) है। यह सार्वजनिक चर वाला एक वर्ग है और कोई विधियाँ (या केवल पढ़ने/लिखने के तरीके) नहीं हैं जिनका उपयोग डेटाबेस के साथ काम करते समय, सॉकेट से संदेशों को पार्स करने आदि के दौरान डेटा स्थानांतरित करने के लिए किया जाता है। डेटा आमतौर पर ऐसी वस्तुओं में लंबी अवधि के लिए संग्रहीत नहीं होता है। यह लगभग तुरंत उस इकाई के प्रकार में परिवर्तित हो जाता है जिस पर हमारा एप्लिकेशन काम करता है। एक इकाई, बदले में, एक डेटा संरचना भी है, लेकिन इसका उद्देश्य अनुप्रयोग के विभिन्न स्तरों पर व्यावसायिक तर्क में भाग लेना है। डीटीओ का उद्देश्य डेटा को एप्लिकेशन से/से ट्रांसपोर्ट करना है। डीटीओ का उदाहरण: एक डेटा संरचना भी है, लेकिन इसका उद्देश्य अनुप्रयोग के विभिन्न स्तरों पर व्यावसायिक तर्क में भाग लेना है। डीटीओ का उद्देश्य डेटा को एप्लिकेशन से/से ट्रांसपोर्ट करना है। डीटीओ का उदाहरण: एक डेटा संरचना भी है, लेकिन इसका उद्देश्य अनुप्रयोग के विभिन्न स्तरों पर व्यावसायिक तर्क में भाग लेना है। डीटीओ का उद्देश्य डेटा को एप्लिकेशन से/से ट्रांसपोर्ट करना है। डीटीओ का उदाहरण:
@Setter
@Getter
@NoArgsConstructor
public class UserDto {
private long id;
private String firstName;
private String lastName;
private String email;
private String password;
}
सब कुछ पर्याप्त स्पष्ट प्रतीत होता है, लेकिन यहाँ हम संकरों के अस्तित्व के बारे में सीखते हैं। हाइब्रिड ऐसी वस्तुएं हैं जिनके पास महत्वपूर्ण तर्क को संभालने के तरीके हैं, आंतरिक तत्वों को संग्रहीत करते हैं, और इसमें एक्सेसर (प्राप्त/सेट) विधियां भी शामिल हैं। ऐसी वस्तुएँ गन्दी होती हैं और नई विधियों को जोड़ना कठिन बनाती हैं। आपको उनसे बचना चाहिए, क्योंकि यह स्पष्ट नहीं है कि वे किस लिए हैं - तत्वों को संग्रहित करना या तर्क को निष्पादित करना?
चर बनाने के सिद्धांत
आइए चरों के बारे में थोड़ा विचार करें। अधिक विशेष रूप से, आइए विचार करें कि उन्हें बनाते समय कौन से सिद्धांत लागू होते हैं:- आदर्श रूप से, आपको एक चर का उपयोग करने से ठीक पहले उसे घोषित करना चाहिए और आरंभ करना चाहिए (एक न बनाएं और इसके बारे में भूल जाएं)।
- जब भी संभव हो, आरंभीकरण के बाद उनके मूल्य को बदलने से रोकने के लिए चर को अंतिम घोषित करें।
- काउंटर वेरिएबल्स के बारे में मत भूलना, जिसे हम आमतौर पर लूप के लिए किसी प्रकार में उपयोग करते हैं। यानी उन्हें जीरो आउट करना न भूलें। नहीं तो हमारे सारे लॉजिक टूट सकते हैं।
- आपको कंस्ट्रक्टर में वेरिएबल्स को इनिशियलाइज़ करने की कोशिश करनी चाहिए।
- यदि किसी संदर्भ के साथ या बिना किसी ऑब्जेक्ट का उपयोग करने के बीच कोई विकल्प है ( new SomeObject() ), बिना विकल्प चुनें, क्योंकि ऑब्जेक्ट का उपयोग करने के बाद इसे अगले कचरा संग्रह चक्र के दौरान हटा दिया जाएगा और इसके संसाधन बर्बाद नहीं होंगे।
- एक चर के जीवनकाल (चर के निर्माण और पिछली बार संदर्भित होने के बीच की दूरी) को यथासंभव छोटा रखें।
- लूप से ठीक पहले लूप में उपयोग किए जाने वाले वेरिएबल्स को इनिशियलाइज़ करें, लूप वाले मेथड की शुरुआत में नहीं।
- हमेशा सबसे सीमित दायरे से शुरू करें और जब आवश्यक हो तभी विस्तार करें (आपको एक चर को यथासंभव स्थानीय बनाने का प्रयास करना चाहिए)।
- प्रत्येक चर का उपयोग केवल एक उद्देश्य के लिए करें।
- एक छिपे हुए उद्देश्य वाले चर से बचें, उदाहरण के लिए दो कार्यों के बीच एक चर विभाजन - इसका मतलब है कि इसका प्रकार उनमें से किसी एक को हल करने के लिए उपयुक्त नहीं है।
तरीकों
फिल्म "स्टार वार्स: एपिसोड III - रिवेंज ऑफ द सिथ" (2005) से
-
नियम #1 - कॉम्पैक्टनेस। आदर्श रूप से, एक विधि 20 पंक्तियों से अधिक नहीं होनी चाहिए। इसका मतलब यह है कि यदि कोई सार्वजनिक विधि "प्रफुल्लित" होती है, तो आपको तर्क को अलग करने और इसे अलग-अलग निजी तरीकों में स्थानांतरित करने के बारे में सोचने की आवश्यकता है।
-
नियम # 2 - अगर , और , जबकि और अन्य बयानों में भारी नेस्टेड ब्लॉक नहीं होने चाहिए: बहुत सारे नेस्टिंग कोड की पठनीयता को काफी कम कर देते हैं। आदर्श रूप से, आपके पास दो से अधिक नेस्टेड {} ब्लॉक नहीं होने चाहिए।
और इन ब्लॉकों में कोड को कॉम्पैक्ट और सरल रखना भी वांछनीय है।
-
नियम # 3 - एक विधि को केवल एक ऑपरेशन करना चाहिए। यही है, यदि कोई विधि सभी प्रकार के जटिल तर्कों का प्रदर्शन करती है, तो हम इसे उप-पद्धतियों में तोड़ देते हैं। नतीजतन, विधि ही एक पहलू होगी जिसका उद्देश्य अन्य सभी कार्यों को सही क्रम में कॉल करना है।
लेकिन क्या होगा अगर ऑपरेशन एक अलग विधि में डालने के लिए बहुत आसान लगता है? सच है, कभी-कभी गौरैया पर तोप दागने जैसा महसूस हो सकता है, लेकिन छोटे तरीके कई फायदे प्रदान करते हैं:
- बेहतर कोड समझ;
- जैसे-जैसे विकास आगे बढ़ता है, तरीके और अधिक जटिल होते जाते हैं। यदि कोई विधि आरंभ करने के लिए सरल है, तो उसकी कार्यक्षमता को जटिल बनाना थोड़ा आसान होगा;
- कार्यान्वयन विवरण छिपे हुए हैं;
- आसान कोड पुन: उपयोग;
- अधिक विश्वसनीय कोड।
-
स्टेपडाउन नियम - कोड को ऊपर से नीचे तक पढ़ा जाना चाहिए: जितना कम आप पढ़ते हैं, आप तर्क में उतने ही गहरे उतरते हैं। और इसके विपरीत, आप जितने ऊंचे जाते हैं, उतने ही सारगर्भित तरीके। उदाहरण के लिए, स्विच स्टेटमेंट गैर-कॉम्पैक्ट और अवांछनीय हैं, लेकिन यदि आप स्विच का उपयोग करने से बच नहीं सकते हैं, तो आपको इसे यथासंभव निम्न स्तर के तरीकों में ले जाने का प्रयास करना चाहिए।
-
विधि तर्क - आदर्श संख्या क्या है? आदर्श रूप से, बिल्कुल भी नहीं :) लेकिन क्या वास्तव में ऐसा होता है? उस ने कहा, आपको जितना संभव हो उतना कम तर्क देने की कोशिश करनी चाहिए, क्योंकि जितने कम होते हैं, एक विधि का उपयोग करना उतना ही आसान होता है और इसका परीक्षण करना उतना ही आसान होता है। जब संदेह हो, तो बड़ी संख्या में इनपुट मापदंडों के साथ विधि का उपयोग करने के लिए सभी परिदृश्यों का अनुमान लगाने का प्रयास करें।
-
इसके अतिरिक्त, इनपुट पैरामीटर के रूप में बूलियन ध्वज वाले तरीकों को अलग करना अच्छा होगा, क्योंकि यह सब स्वयं का अर्थ है कि विधि एक से अधिक ऑपरेशन करती है (यदि सही है, तो एक काम करें; यदि गलत है, तो दूसरा करें)। जैसा कि मैंने ऊपर लिखा है, यह अच्छा नहीं है और यदि संभव हो तो इससे बचना चाहिए।
-
यदि किसी विधि में बड़ी संख्या में इनपुट पैरामीटर हैं (एक चरम 7 है, लेकिन आपको वास्तव में 2-3 के बाद सोचना शुरू करना चाहिए), कुछ तर्कों को एक अलग वस्तु में समूहीकृत किया जाना चाहिए।
-
यदि कई समान (अतिभारित) विधियाँ हैं, तो समान मापदंडों को उसी क्रम में पारित किया जाना चाहिए: इससे पठनीयता और उपयोगिता में सुधार होता है।
-
जब आप किसी विधि में पैरामीटर पास करते हैं, तो आपको सुनिश्चित होना चाहिए कि वे सभी उपयोग किए जाते हैं, अन्यथा आपको उनकी आवश्यकता क्यों है? किसी भी अप्रयुक्त पैरामीटर को इंटरफ़ेस से बाहर करें और इसके साथ काम करें।
- कोशिश/पकड़ प्रकृति में बहुत अच्छा नहीं दिखता है, इसलिए इसे एक अलग मध्यवर्ती विधि (अपवादों को संभालने के लिए एक विधि) में स्थानांतरित करना एक अच्छा विचार होगा:
public void exceptionHandling(SomeObject obj) { try { someMethod(obj); } catch (IOException e) { e.printStackTrace(); } }
GO TO FULL VERSION