क्या सी # 6.0 का नया अशक्त-संचालक संचालक कानून के खिलाफ जाता है?


29

Demeter के कानून में कहा गया है निम्नलिखित:

  • प्रत्येक इकाई को अन्य इकाइयों के बारे में केवल सीमित ज्ञान होना चाहिए: केवल इकाइयाँ जो वर्तमान इकाई से संबंधित "बारीकी से" हैं।
  • प्रत्येक इकाई को केवल अपने दोस्तों से बात करनी चाहिए; अजनबियों से बात न करें।
  • केवल अपने तात्कालिक दोस्तों से बात करें।

C # 6.0 ने एक नया ऑपरेटर शुरू किया जिसे null-सशर्त ऑपरेटर कहा जाता है । IMHO, यह कोडिंग को आसान बनाता है और पठनीयता में सुधार करता है। लेकिन इससे अधिक युग्मित कोड लिखना भी आसान हो जाता है, क्योंकि क्लास फ़ील्ड के माध्यम से नेविगेट करना आसान होता है, पहले से ही अशक्तता (कुछ var x = A?.B?.C?.D?.E?.F?) के लिए जाँच ।

क्या यह बताना सही है कि यह नया ऑपरेटर कानून के कानून के खिलाफ जाता है?


2
आप ऐसा क्यों मानते हैं कि A?.B?.C?.D?.E?.F?इसका उल्लंघन होगा - LoD इस बारे में नहीं है कि कितने डॉट्स हैं और यदि कॉलिंग पद्धति में संरचना के बारे में ऐसी जानकारी है जो इसके बिंदुओं का उल्लंघन नहीं करती है, तो ऐसी कॉल पूरी तरह से स्वीकार्य होगी। ऐसी है कि कोड सकता लोद का उल्लंघन कहना है कि यह के सभी उपयोगों पर्याप्त नहीं है कर का उल्लंघन लोद।

14
पढ़ना " कानून का कानून एक मत गणना व्यायाम नहीं है "? यह इस सटीक उदाहरण पर चर्चा करता है।
आउटिस

@outis: उत्कृष्ट पढ़ा। मैं यह नहीं कह रहा हूं कि प्रत्येक कोड X.Y.Z.W.U"कानून" का उल्लंघन है। लेकिन, मेरे अनुभव में कोड के साथ काम करना, 90% समय यह सिर्फ सादे बदसूरत युग्मित कोड है।
आर्थर रिज़ो

2
@ArthurRizzo, लेकिन अशक्त सशर्त ऑपरेटर के साथ LoD के खिलाफ जाने में कोई समस्या नहीं है। यह वह कोड है जो गलती पर है। ऑपरेटर इसे पढ़ने वाले मानव को सरल बनाने के लिए सिर्फ एक उपकरण है। .?से अधिक नहीं लोद का उल्लंघन करती है +या -नहीं करता है।

1
आरसी मार्टिन शुद्ध डेटा वर्गों और व्यवहार वर्गों के बीच अंतर करता है। यदि एक्सेस किए गए गुण व्यवहार वर्ग के आंतरिक डेटा को उजागर करते हैं, तो स्निपेट निश्चित रूप से LoD का उल्लंघन करता है, लेकिन इसका अशक्त-संचालक से कोई लेना-देना नहीं है। वैसे भी, गुण आंतरिक डेटा को उजागर करने के लिए बाध्य नहीं हैं, जो एक गंध हो सकता है, लेकिन LoD का उल्लंघन नहीं करता है। आरसी मार्टिन के अनुसार स्कीमा शुद्ध डेटा वर्गों के साथ बिल्कुल मान्य हो सकता है।
पॉल केर्ट्सचर

जवाबों:


44

क्या यह बताना सही है कि यह नया ऑपरेटर कानून के कानून के खिलाफ जाता है?

नहीं *


* शून्य सशर्त ऑपरेटर भाषा और .NET फ्रेमवर्क के भीतर एक उपकरण है। किसी भी उपकरण में दुर्व्यवहार करने और उन तरीकों से उपयोग करने की क्षमता है जो किसी दिए गए एप्लिकेशन की स्थिरता को नुकसान पहुंचा सकते हैं।

लेकिन तथ्य यह है कि एक उपकरण कर सकते हैं दुरुपयोग होने का अर्थ यह नहीं है कि यह है कि हो सकता है है के साथ दुर्व्यवहार किया जा रहा है, और न ही किसी विशेष उपकरण सिद्धांत (रों) कि आयोजित किया जा सकता का उल्लंघन करता है।

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

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


foo = new FiveDMatrix(); foo.get(0).get(0).get(0).get(0).set(0,1);ठीक होगा (और इससे भी बुरा नहीं foo[0][0][0][0][0] = 1) ... और बहुत सी अन्य परिस्थितियाँ जहाँ इस तरह से LoD का उल्लंघन नहीं होता है।

@ मिचेल्ट जब आप उस आयामीता के मैट्रिक्स में होने लगते हैं, तो ऐसा लगता है कि सूचकांकों को वेक्टर / टपल / सरणी के रूप में व्यवहार करना आसान हो जाएगा और मैट्रिक्स वर्ग के आंतरिक लोगों को इस बात की चिंता करने दें कि डेटा वास्तव में कैसे संग्रहीत किया जाता है। (जो, अब जब मैं इसके बारे में सोचता हूं, तो लॉ ऑफ़ डेमेटर का एक अनुप्रयोग है, कम से कम जैसा कि यह एनकैप्सुलेशन से संबंधित है।)
जेएबी

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

1
@JAB मैं एक उदाहरण के साथ आने की कोशिश कर रहा था। एक बेहतर एक संभावना होगी Dom file = prase("some.xml"); file.get(tag1).getChild().get(tag2).getChild() ...- यह कुछ गूंगा कोड की संरचना को संसाधित करने का एक मुद्दा है। यह अजनबी नहीं है ... यह सिर्फ गूंगा है। .?हो जाता है बहुत ऐसी संरचनाओं में उपयोगी है।

10

की तरह।

यदि आप केवल एक एक्सेस ( a?.Foo) कर रहे हैं तो यह इसके बराबर है:

a == null ? null : a.Foo

जो कि ज्यादातर लोग सहमत होंगे कानून का उल्लंघन नहीं है। उस बिंदु पर, यह पठनीयता में सुधार करने के लिए सिंटैक्टिक शुगर है।

इससे अधिक कुछ भी, और यह संभवतः कानून के कानून का उल्लंघन होगा, और यह सुविधा उस तरह के उपयोग को बढ़ावा देती है। मैं यह भी कहूंगा कि उपरोक्त "अच्छा" उपयोग केवल भाषा के इस प्रकार के परिवर्तन को वारंट करने के लिए पर्याप्त नहीं है, इसलिए मुझे उम्मीद है कि यह कम स्पष्ट रूप से अच्छे उपयोग का समर्थन करने के लिए बनाया गया था।

उस ने कहा, यह याद रखने योग्य है कि कानून का कानून प्रति कानून नहीं है, लेकिन एक दिशानिर्देश के अधिक है। बहुत सारे कोड इसका उल्लंघन करते हैं और अच्छी तरह से काम करते हैं। कभी-कभी डिजाइन या कोड की सादगी कानून के कानून का उल्लंघन करने से उत्पन्न जोखिम से अधिक होती है।


इससे अधिक कुछ भी जरूरी नहीं है कि LoD उदा। बिल्डर पैटर्न
jk।

@Telastyn: हम जिस नई भाषा सिंटेक्स के बारे में बात कर रहे हैं वह समर्थन विधि कॉल करती है: a?.Func1(x)?.Func2(y) अशक्त सहवर्ती ऑपरेटर कुछ और है।
बेन वायगेट

@BenVoigt - आह, मैं लेख से दूर जा रहा था, जिसने संकेत दिया कि यह केवल खेतों, गुणों और अनुक्रमकों के साथ काम करता है। मेरे पास MSVS2015 का परीक्षण करना आसान नहीं था। तुम सही हो।
21:39 पर तेलस्टिन

1
a। .Foo == null के बराबर नहीं है? null: a.Foo। पूर्व केवल एक बार मूल्यांकन करता है, बाद वाला दो बार इसका मूल्यांकन करता है। अगर यह एक पुनरावृत्ति करने वाले थे।
लोरेन Pechtel

9

नहीं, चलो दोनों ऑपरेटर को अपने दम पर मानते हैं, और इसके लिए आपके पास भारी जंजीर का उपयोग है।

अपने आप .?Aही वर्ग के ज्ञान की समान मात्रा पर निर्भर करता है कि वाम-मूल्य क्या है और विधि द्वारा लौटाए गए प्रकार के अनुसार .A != null, अर्थात। इसके बारे में यह जानना आवश्यक है कि Aसंपत्ति मौजूद है और एक मूल्य देता है जिसकी तुलना की जा सकती है null

हम केवल यह तर्क दे सकते हैं कि यदि टाइप की गई संपत्तियां हैं तो यह डेमेटर के कानून का उल्लंघन करता है। हमें Aएक ठोस प्रकार के रूप में भी मजबूर नहीं किया गया है (इसका मूल्य एक व्युत्पन्न प्रकार का हो सकता है)। यहां कपलिंग न्यूनतम है।

अब विचार करते हैं var x = A?.B?.C?.D?.E?.F

जिसका अर्थ है कि Aएक प्रकार का होना चाहिए जो अशक्त हो सकता है, या उसके पास एक Bसंपत्ति हो सकती है , जो एक प्रकार का होना चाहिए जो शून्य हो सकता है या उसके पास संपत्ति हो सकती Cहै, और इसी तरह जब तक Eसंपत्ति का प्रकार कुछ ऐसा होता है जो अशक्त हो सकता है या हो सकता है एक Fसंपत्ति हो सकती है ।

दूसरे शब्दों में, हमें ऐसा करने की ज़रूरत है कि या तो एक सांख्यिकीय रूप से टाइप की गई भाषा है या टाइपिंग में एक बाधा लागू की है जो टाइपिंग ढीली होने पर वापस आ सकती है। अधिकांश मामलों में C # स्थिर टाइपिंग का उपयोग करता है, इसलिए हमने कुछ भी नहीं बदला है।

यदि हमारे पास था तो निम्न कोड कानून का भी उल्लंघन करेगा:

ExplicitType x;
var b = A.B;
if (b == null)
  x = null;
else
{
  var c = b.C;
  if (c == null)
    x = null;
  else
  {
    var d = c.D;
    if (d == null)
      x = null;
    else
    {
      var e = d.E;
      if (e == null)
        x = null;
      else
        x = e.F;
    }
  }
}

जो बिलकुल एक जैसा हो । यह कोड जो विभिन्न तत्वों के युग्मन का उपयोग कर रहा है , को युग्मन की पूरी श्रृंखला के बारे में "जानना" चाहिए, लेकिन यह कोड का उपयोग कर रहा है जो ऐसा करने के लिए डेमेटर के कानून का उल्लंघन नहीं करता है, प्रत्येक इकाई के साथ एक अच्छी तरह से परिभाषित युग्मन है। अगला।


3
+1 नया ऑपरेटर केवल आपके द्वारा बताए गए कड़वे नुस्खा के लिए सिंटैक्टिक चीनी है।
रॉस पैटरसन

1
ठीक है, अगर कोई देवता ऐसा कोड लिखता है जो ऐसा लगता है कि मुझे लगता है कि यह नोटिस करना आसान है कि कुछ सही नहीं हो सकता है। मुझे पता है कि ऑपरेटर 100% सिन्थेटिक चीनी है, लेकिन फिर भी, मुझे लगता है कि लोग var x = A?.B?.C?.D?.E?.Fअंत में समान होने पर भी उन सभी की तुलना में कुछ लिखने की अधिक सुविधा प्राप्त करते हैं ।
आर्थर रिज़ो

2
यह नोटिस करना आसान है कि कुछ सही नहीं है A?.B?.C?.D?.E?.Fक्योंकि इसमें कम है जो गलत हो सकता है; या तो हमें Fउस रास्ते से जाने की कोशिश करनी चाहिए , या हमें नहीं करनी चाहिए, जबकि लंबे समय तक इसके भीतर त्रुटियाँ हो सकती हैं और साथ ही साथ यह त्रुटि भी सही नहीं है।
जॉन हन्ना

@ArthurRizzo लेकिन अगर आप उपरोक्त प्रकार के कोड को LoD उल्लंघनों के साथ जोड़ते हैं, तो यह उन मामलों में याद करना आसान है जहां कोई शून्य जाँच आवश्यक नहीं है और आप बस कर सकते हैं A.B.C.D। यह बहुत आसान है कि दो अलग-अलग चीजों के बजाय एक ही चीज़ को देखना (जंजीरदार संपत्ति की पहुंच) है जो एक बहुत अप्रासंगिक विवरण (शून्य-जाँच) पर निर्भर है
बेन आरोनसन

5

ऑब्जेक्ट को एन्कैप्सुलेटिंग व्यवहार या डेटा धारण करने के उद्देश्य से बनाया जा सकता है, और वस्तुओं को बाहरी कोड के साथ साझा करने या उनके निर्माता द्वारा निजी तौर पर आयोजित किए जाने के उद्देश्य से बनाया जा सकता है।

ऑब्जेक्ट्स जो एन्कैप्सुलेटिंग व्यवहार (साझा या नहीं) के उद्देश्य से बनाए गए हैं, या बाहरी कोड के साथ साझा किए जाने के लिए (चाहे वे व्यवहार या डेटा को एनकैप्सुलेट करते हैं) आम तौर पर उनके सतह इंटरफ़ेस के माध्यम से एक्सेस किया जाना चाहिए। जब उनके निर्माता द्वारा विशेष रूप से उपयोग के लिए डेटा-होल्डिंग ऑब्जेक्ट बनाए जाते हैं, हालांकि, "गहरी" एक्सेस से बचने के सामान्य लॉ-ऑफ-डेमेटर कारण लागू नहीं होते हैं। यदि एक वर्ग का हिस्सा जो ऑब्जेक्ट में डेटा को स्टोर या मैनिपुलेट करता है, उसे इस तरह से बदल दिया जाता है, जिसमें अन्य कोड को समायोजित करने की आवश्यकता होती है, तो यह गारंटी देना संभव होगा कि ऐसे सभी कोड अपडेट हो जाएं - क्योंकि जैसा कि ऊपर उल्लेख किया गया है - ऑब्जेक्ट के लिए बनाया गया था एक वर्ग का विशेष उपयोग।

जबकि मुझे लगता है? ऑपरेटर शायद बेहतर डिज़ाइन किया जा सकता था, पर्याप्त परिस्थितियां हैं जहां ऑब्जेक्ट्स नेस्टेड डेटा संरचनाओं का उपयोग करते हैं कि ऑपरेटर के पास कई उपयोग के मामले हैं जो डेमेटर के कानून द्वारा व्यक्त किए गए सिद्धांतों का उल्लंघन नहीं करेंगे। तथ्य यह है कि यह LoD का उल्लंघन करने के लिए इस्तेमाल किया जा सकता है ऑपरेटर के खिलाफ एक तर्क के रूप में नहीं लिया जाना चाहिए, क्योंकि यह "से बेहतर नहीं है।" उस संबंध में ऑपरेटर।


डेटा रखने वाली वस्तुओं पर क़ानून का कानून लागू क्यों नहीं होता?
तेलस्टिन

2
@ टेलस्टाइन: एलओडी का उद्देश्य उन समस्याओं से बचना है, जो हो सकता है कि कोड का एक टुकड़ा आंतरिक वस्तुओं तक पहुंच जाए जो कुछ और हेरफेर या देखभाल कर सकता है । यदि ब्रह्मांड में और कुछ भी संभवतः आंतरिक वस्तुओं की स्थिति के बारे में हेरफेर या देखभाल नहीं कर सकता है, तो ऐसी समस्याओं के खिलाफ रक्षा करने की कोई आवश्यकता नहीं है।
सुपरकैट

मुझे यकीन नहीं है कि मैं सहमत हूं। ऐसा नहीं है कि अन्य चीजें डेटा को संशोधित करने की परवाह कर सकती हैं, यह है कि आप एक पथ के माध्यम से निहित वस्तु के लिए युग्मन कर रहे हैं (अनिवार्य रूप से युग्मन के तीन बिंदु - दो वस्तुओं और उनके संबंध)। कभी-कभी वह कपलिंग कोई बड़ी बात नहीं होती, लेकिन फिर भी मुझे बदबूदार लगती है।
तेलस्टिन

@ टेलस्टाइन: रास्तों के बारे में आपकी बात अच्छी है, लेकिन मुझे लगता है कि मेरी बात ठीक है। कई पथों के माध्यम से किसी वस्तु तक पहुँचने से उन रास्तों के बीच युग्मन बनता है। यदि कुछ पहुंच उथले मार्ग से होती है, तो गहरे मार्ग से पहुंच के साथ-साथ अवांछित युग्मन हो सकता है। यदि सभी पहुंच एक विशेष गहरे मार्ग से होती है, तो, युगल के लिए उस गहरे मार्ग के लिए कुछ भी नहीं होगा।
सुपरकैट

@ टेलस्टाइन डेटा को गहराई तक ले जाने के लिए डेटासट्रक्चर को पार करना बिल्कुल ठीक है। यह नेस्टेड विधि कॉल के समान नहीं है। आपको कभी-कभी डेटास्ट्रक्चर को जानने की आवश्यकता होती है और इसे किस प्रकार से नेस्ट किया जाता है, उसी तरह यह एक सेवा और अपने स्वयं के नेस्टेड सेवाओं / रिपॉजिटरी आदि जैसी वस्तुओं के लिए नहीं जाता है
प्रति हॉर्न्ज-शियरबेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.