क्या एक स्तरित सॉफ़्टवेयर वास्तुकला में एक ही परत की वस्तुओं के बीच निर्भरता होना समस्याग्रस्त है?


12

एन-लेयर आर्किटेक्चर और डिपेंडेंसी इंजेक्शन के साथ एक मध्यम-बड़े सॉफ़्टवेयर को ध्यान में रखते हुए, मैं यह कहने के लिए सहज हूं कि एक परत से संबंधित ऑब्जेक्ट निचली परतों से वस्तुओं पर निर्भर हो सकता है लेकिन उच्चतर परतों से वस्तुओं पर कभी नहीं।

लेकिन मुझे यकीन नहीं है कि उन वस्तुओं के बारे में क्या सोचना है जो एक ही परत की अन्य वस्तुओं पर निर्भर हैं।

एक उदाहरण के रूप में, आइए तीन परतों और छवि में एक जैसी कई वस्तुओं के साथ एक एप्लिकेशन को मान लें। स्पष्ट रूप से ऊपर-नीचे निर्भरताएं (हरे तीर) ठीक हैं, नीचे-ऊपर (लाल तीर) ठीक नहीं हैं, लेकिन एक ही परत (पीले तीर) के अंदर निर्भरता के बारे में क्या?

यहाँ छवि विवरण दर्ज करें

परिपत्र निर्भरता को छोड़कर, मैं किसी भी अन्य मुद्दे के बारे में उत्सुक हूं जो इस मामले में उत्पन्न हो सकता है और स्तरित वास्तुकला का कितना उल्लंघन हो रहा है।


यदि आपके पास चक्र नहीं है, तो एक ऐसी परत में जहां आपके पास horysontal लिंक हैं, उप-परतों में विभाजित होते हैं जो केवल परतों के बीच निर्भरता रखते हैं
अधिकतम 6

जवाबों:


10

हां, एक परत की वस्तुओं में एक दूसरे के बीच प्रत्यक्ष निर्भरता हो सकती है, कभी-कभी चक्रीय भी - जो वास्तव में विभिन्न परतों में वस्तुओं के बीच अनुमत निर्भरता के लिए मुख्य अंतर बनाता है, जहां या तो कोई प्रत्यक्ष निर्भरता की अनुमति नहीं है, या बस एक सख्त निर्भरता है। दिशा ।

हालांकि, इसका मतलब यह नहीं है कि उन्हें इस तरह की निर्भरता अनियंत्रित तरीके से होनी चाहिए। यह वास्तव में इस बात पर निर्भर करता है कि आपकी परतें क्या दर्शाती हैं, सिस्टम कितना बड़ा है और भागों की जिम्मेदारी क्या होनी चाहिए। ध्यान दें कि "स्तरित वास्तुकला" एक अस्पष्ट शब्द है, जो कि विभिन्न प्रकार की प्रणालियों में वास्तव में इसका मतलब है, की एक विशाल विविधता है।

उदाहरण के लिए, मान लें कि आपके पास एक "क्षैतिज स्तरित प्रणाली" है, जिसमें एक डेटाबेस परत, एक व्यवसाय परत और एक उपयोगकर्ता इंटरफ़ेस (UI) परत है। कहते हैं कि UI परत में कम से कम कई दर्जनों अलग-अलग संवाद कक्षाएं हैं।

कोई ऐसा डिज़ाइन चुन सकता है जहाँ कोई भी डायलॉग क्लास सीधे दूसरे डायलॉग क्लास पर निर्भर न हो। कोई ऐसा डिज़ाइन चुन सकता है जहाँ "मुख्य संवाद" और "उप संवाद" मौजूद हों और "मुख्य" से "उप" संवादों तक सीधे निर्भरता हो। या कोई ऐसा डिज़ाइन पसंद कर सकता है जहाँ कोई भी मौजूदा UI वर्ग उसी परत से किसी अन्य UI वर्ग का उपयोग / पुन: उपयोग कर सकता है।

ये सभी संभव डिज़ाइन विकल्प हैं, हो सकता है कि आपके द्वारा बनाए जा रहे सिस्टम के प्रकार के आधार पर अधिक या कम समझदार हो, लेकिन उनमें से कोई भी आपके सिस्टम की "लेयरिंग" को अमान्य नहीं बनाता है।


यूआई उदाहरण पर जारी रखते हुए, आंतरिक निर्भरता होने के समर्थक और विपक्ष क्या हैं? मैं देख सकता हूं कि यह आसान पुन: उपयोग करता है और चक्रीय निर्भरता का परिचय देता है, जो कि इस्तेमाल की गई डीआई पद्धति के आधार पर एक समस्या हो सकती है। और कुछ?
Bracco23

@ bracco23: "आंतरिक" निर्भरता वाले पेशेवरों और विपक्षों में वही होता है, जो मनमाने ढंग से निर्भरता वाले होने के विपक्ष के पेशेवरों के रूप में होता है। "विपक्ष" वे घटकों को पुन: उपयोग करने के लिए कठिन और कठिन परीक्षण करने के लिए बनाते हैं, विशेष रूप से अन्य घटकों से अलगाव में। पेशेवरों, स्पष्ट निर्भरता चीजें हैं जो सामंजस्य की आवश्यकता होती है उपयोग करने, समझने, प्रबंधन और परीक्षण करने के लिए आसान है।
डॉक्टर ब्राउन

14

मैं यह कहने के लिए सहज हूं कि एक परत से संबंधित वस्तु निचली परतों से वस्तुओं पर निर्भर हो सकती है

सच कहूं तो, मुझे नहीं लगता कि आपको इसके साथ सहज होना चाहिए। जब कुछ भी लेकिन एक तुच्छ प्रणाली के साथ काम करते हैं, तो मैं सभी परतों को केवल अन्य परतों के सार पर निर्भर करना सुनिश्चित करना चाहता हूं; निम्न और उच्चतर दोनों।

इसलिए उदाहरण के लिए, Obj 1पर निर्भर नहीं होना चाहिए Obj 3। इस पर उदाहरण के तौर पर निर्भरता IObj 3होनी चाहिए और यह बताया जाना चाहिए कि उस समय में किस अमूर्त को लागू करना है। यह बताने वाली बात किसी भी स्तर पर असंबंधित होनी चाहिए क्योंकि यह काम उन निर्भरताओं को मैप करने के लिए है। यह एक Io कंटेनर हो सकता है, कस्टम कोड जिसे उदाहरण के mainलिए शुद्ध DI का उपयोग किया जाता है । या एक धक्का पर यह एक सेवा लोकेटर भी हो सकता है। बावजूद, निर्भरताएं परतों के बीच मौजूद नहीं होती हैं जब तक कि वह चीज मैपिंग प्रदान नहीं करती है।

लेकिन मुझे यकीन नहीं है कि उन वस्तुओं के बारे में क्या सोचना है जो एक ही परत की अन्य वस्तुओं पर निर्भर हैं।

मेरा तर्क है कि यह केवल समय है जब आपके पास प्रत्यक्ष निर्भरता होनी चाहिए । यह उस परत के आंतरिक कामकाज का हिस्सा है और इसे अन्य परतों को प्रभावित किए बिना बदला जा सकता है। तो यह एक हानिकारक युग्मन नहीं है।


जवाब के लिए धन्यवाद। हां, परत को वस्तुओं को नहीं, बल्कि इंटरफेस को उजागर करना चाहिए, मुझे पता है कि लेकिन मैंने इसे सरलता के लिए छोड़ दिया।
Bracco23

4

आइए इसे व्यावहारिक रूप से देखें

यहाँ छवि विवरण दर्ज करें

Obj 3अब Obj 4मौजूद है। तो क्या? हम क्यों परवाह करते हैं?

डीआईपी का कहना है

"उच्च-स्तरीय मॉड्यूल को निम्न-स्तर के मॉड्यूल पर निर्भर नहीं होना चाहिए। दोनों को अमूर्तता पर निर्भर होना चाहिए।"

ठीक है, लेकिन क्या सभी वस्तुएं अमूर्त नहीं हैं?

डीआईपी भी कहता है

"सार विवरण पर निर्भर नहीं होना चाहिए। विवरण सार पर निर्भर होना चाहिए।"

ठीक है, लेकिन, अगर मेरी वस्तु ठीक से एनकैप्सुलेटेड है, तो क्या यह कोई विवरण नहीं छिपाता है?

कुछ लोग आँख बंद करके इस बात पर जोर देना पसंद करते हैं कि हर वस्तु को एक कीवर्ड इंटरफ़ेस की आवश्यकता है। मैं उनमें से नहीं हूं। मैं आँख बंद करके यह कहना पसंद करता हूं कि यदि आप उनका उपयोग नहीं करने जा रहे हैं, तो आपको बाद में उनके जैसे कुछ की जरूरत से निपटने के लिए एक योजना की आवश्यकता होगी।

यदि आपका कोड हर रिलीज़ पर पूरी तरह से रिफलेक्टर-सक्षम है, तो आप ज़रूरत पड़ने पर बाद में इंटरफेस निकाल सकते हैं। यदि आपने ऐसा कोड प्रकाशित किया है जिसे आप फिर से इकट्ठा नहीं करना चाहते हैं और अपने आप को चाहते हैं कि आप एक इंटरफ़ेस के माध्यम से बात कर रहे हैं तो आपको एक योजना की आवश्यकता होगी।

Obj 3जानता है Obj 4मौजूद है। लेकिन क्या यह Obj 3पता है कि क्या Obj 4ठोस है?

यह यहीं है क्यों यह newहर जगह फैल नहीं करने के लिए बहुत अच्छा है। अगर Obj 3यह नहीं पता है कि Obj 4क्या ठोस है, संभावना है क्योंकि यह इसे नहीं बनाया है, तो अगर आप बाद में झपकी लेते हैं और Obj 4एक अमूर्त वर्ग में बदल जाते Obj 3हैं तो परवाह नहीं करेंगे।

यदि आप ऐसा कर सकते हैं तो Obj 4सभी के साथ पूरी तरह से अमूर्त है। शुरू से ही उनके बीच एक इंटरफेस बनाने वाली एकमात्र चीज आपको यह आश्वासन देती है कि कोई व्यक्ति गलती से कोड जोड़ता है जो Obj 4अभी दूर ठोस है। संरक्षित निर्माणकर्ता उस जोखिम को कम कर सकते हैं लेकिन इससे एक और सवाल बनता है:

क्या Obj 3 और Obj 4 एक ही पैकेज में हैं?

वस्तुओं को अक्सर किसी तरह से समूहित किया जाता है (पैकेज, नाम स्थान आदि)। जब समूह बुद्धिमानी से समूह के बजाय समूह के भीतर अधिक संभावित प्रभावों को बदलते हैं।

मुझे फीचर के आधार पर ग्रुप बनाना पसंद है। तो Obj 3और Obj 4एक ही समूह और परत में हैं यह बहुत संभावना नहीं है कि आप एक प्रकाशित किया है और यह refactor करने के लिए, जबकि केवल एक दूसरे को बदलने की आवश्यकता के नहीं करना चाहता। इसका मतलब यह है कि इन वस्तुओं को एक स्पष्ट आवश्यकता होने से पहले उन दोनों के बीच एक अमूर्त डाल से लाभ होने की संभावना कम है।

यदि आप एक समूह सीमा पार कर रहे हैं, तो यह वास्तव में एक अच्छा विचार है कि दोनों तरफ की वस्तुओं को स्वतंत्र रूप से अलग-अलग किया जाए।

यह सरल होना चाहिए लेकिन दुर्भाग्य से जावा और सी # दोनों ने दुर्भाग्यपूर्ण विकल्प बनाए हैं जो इसे जटिल बनाते हैं।

C # में प्रत्येक कीवर्ड इंटरफ़ेस को एक Iउपसर्ग के साथ नाम देना परंपरा है । वह ग्राहकों को जानने के लिए मजबूर करता है कि वे एक कीवर्ड इंटरफ़ेस से बात कर रहे हैं। वह रिफ्लेक्टरिंग योजना के साथ खिलवाड़ करता है।

जावा में यह एक बेहतर नामकरण पैटर्न का उपयोग करने की परंपरा है: FooImple implements Fooहालांकि, यह केवल स्रोत कोड स्तर पर मदद करता है क्योंकि जावा एक अलग बाइनरी में कीवर्ड इंटरफेस को संकलित करता है। इसका मतलब है कि जब आप Fooकंक्रीट से अमूर्त ग्राहकों के लिए रिफ्लेक्टर करते हैं जिन्हें कोड के एक भी चरित्र की आवश्यकता नहीं होती है जिसे अभी भी बदला हुआ है।

यह इन विशेष भाषाओं में यह BUGS है जो लोगों को औपचारिक अमूर्तता से दूर रखने में सक्षम बनाता है जब तक कि उन्हें वास्तव में इसकी आवश्यकता न हो। आपने यह नहीं कहा कि आप किस भाषा का उपयोग कर रहे हैं, लेकिन समझते हैं कि कुछ ऐसी भाषाएं हैं, जिनमें बस ये समस्याएं नहीं हैं।

आपने यह नहीं कहा कि आप किस भाषा का उपयोग कर रहे हैं, इसलिए मैं आपसे आग्रह करूंगा कि आप अपनी भाषा और स्थिति का सावधानीपूर्वक विश्लेषण करें, इससे पहले कि आप यह तय करें कि यह हर जगह कीवर्ड इंटरफेस होने वाला है।

YAGNI सिद्धांत यहां एक महत्वपूर्ण भूमिका निभाता है। लेकिन ऐसा करता है "कृपया अपने आप को पैर में गोली मारना मुश्किल है"।


0

उपरोक्त उत्तरों के अलावा, मुझे लगता है कि यह आपको अलग-अलग दृष्टिकोणों से देखने में मदद कर सकता है।

उदाहरण के लिए, निर्भरता नियम के दृष्टिकोण से। DR एक नियम है जो रॉबर्ट सी। मार्टिन ने अपने प्रसिद्ध क्लीन आर्किटेक्चर के लिए सुझाया है ।

इसे कहते हैं

स्रोत कोड निर्भरता केवल उच्च-स्तर की नीतियों की ओर, आवक को इंगित करना चाहिए।

द्वारा उच्च स्तर की नीतियों , वह इसका मतलब है उच्च स्तर की कपोल-कल्पना की। ऐसे घटक जो कार्यान्वयन विवरण पर लीक होते हैं, उदाहरण के लिए कंक्रीट कक्षाओं या डेटा संरचनाओं के विपरीत इंटरफेस या अमूर्त वर्ग।

बात यह है कि, नियम अंतर-परत निर्भरता तक सीमित नहीं है। यह केवल कोड के टुकड़ों के बीच निर्भरता को इंगित करता है, चाहे वह जिस स्थान या परत का हो।

तो नहीं, एक ही परत के तत्वों के बीच निर्भरता होने के साथ कुछ भी गलत नहीं है। हालाँकि, निर्भरता अभी भी स्थिर निर्भरता सिद्धांत के साथ लागू करने के लिए लागू किया जा सकता है

एक अन्य दृष्टिकोण एसआरपी है।

Decoupling हानिकारक निर्भरता को तोड़ने और निर्भरता व्युत्क्रम (IoC) जैसी कुछ सर्वोत्तम प्रथाओं के साथ व्यक्त करने का हमारा तरीका है। हालांकि, वे तत्व जो बदलने के कारणों को साझा करते हैं वे डिकॉउलिंग के लिए कारण नहीं देते हैं क्योंकि बदलने के लिए एक ही कारण वाले तत्व एक ही समय (बहुत संभावना) में बदल जाएंगे और उन्हें एक ही समय में भी तैनात किया जाएगा। यदि यह मामला है के बीच Obj3और Obj4उसके बाद, एक बार फिर, वहाँ स्वाभाविक कुछ भी गलत नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.