ग्लोबल्स किसी डेटाबेस से अलग कैसे हैं?


250

मैं सिर्फ इस पुराने सवाल के बारे में पूछ रहा था कि वैश्विक राज्य के बारे में क्या बुराई है, और शीर्ष-मतदान, स्वीकृत उत्तर का दावा करता है कि आप वैश्विक चर के साथ काम करने वाले किसी भी कोड पर भरोसा नहीं कर सकते, क्योंकि कुछ अन्य कोड कहीं और साथ आ सकते हैं और इसे संशोधित कर सकते हैं मूल्य और फिर आपको नहीं पता कि आपके कोड का व्यवहार क्या होगा क्योंकि डेटा अलग है! लेकिन जब मैं उस पर गौर करता हूं, तो मैं मदद नहीं कर सकता, लेकिन लगता है कि यह वास्तव में कमजोर व्याख्या है, क्योंकि यह कैसे डेटाबेस में संग्रहीत डेटा के साथ काम करने से अलग है?

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

लेकिन अगर आप जिस डेटा के साथ काम कर रहे हैं, वह किसी बाहरी स्रोत से आ रहा है, जिस पर आपके कोड का कोई नियंत्रण नहीं है, जैसे कि डेटाबेस (या उपयोगकर्ता इनपुट, या नेटवर्क सॉकेट, या फ़ाइल, आदि ...) और इसमें कुछ भी गलत नहीं है। इसके साथ ही, फिर कोड के भीतर वैश्विक डेटा कैसे है - जो आपके प्रोग्राम पर बहुत अधिक नियंत्रण है - किसी तरह एक बुरी बात जब यह स्पष्ट रूप से पूरी तरह से सामान्य सामान की तुलना में बहुत कम खराब होता है जिसे कोई भी समस्या के रूप में नहीं देखता है?


117
वयोवृद्ध सदस्यों को
हठधर्मिता को

10
एक आवेदन में, आप आमतौर पर डेटाबेस तक पहुंचने के लिए एक साधन प्रदान करते हैं, इस मतलब को उन कार्यों को पास किया जाता है जो डेटाबेस तक पहुंचना चाहते हैं। आप वैश्विक चर के साथ ऐसा नहीं करते हैं, आप बस जानते हैं कि वे हाथ में हैं। यह एक महत्वपूर्ण अंतर है।
एंडी

45
वैश्विक स्थिति एक एकल डेटाबेस के साथ होती है, जिसमें एकल पंक्ति के साथ एक एकल पंक्ति होती है जिसमें कई स्तंभों को एक संख्या में मनमाने ढंग से अनुप्रयोगों तक पहुंचाया जाता है।
बेविनक्यू

42
डेटाबेस भी बुरे हैं।
स्टिग हेमर

27
आपके द्वारा यहां किए गए तर्क को "उल्टा" करना मनोरंजक है और दूसरी दिशा में जाना है। एक संरचना जिसमें एक अन्य संरचना के लिए एक संकेतक होता है, तार्किक रूप से एक तालिका की एक पंक्ति में एक विदेशी कुंजी होती है जो किसी अन्य तालिका की दूसरी पंक्ति की कुंजी होती है। किसी डेटाबेस में डेटा में हेरफेर करने से किसी भी अलग लिंक से चलने सहित किसी भी कोड के साथ काम कैसे किया जाता है ? उत्तर: यह नहीं है। प्रश्न: फिर हम ऐसे विभिन्न उपकरणों का उपयोग करके इन-मेमोरी डेटा संरचनाओं और इन-डेटाबेस डेटा संरचनाओं में हेरफेर क्यों करते हैं? उत्तर: मुझे सच में नहीं पता! अच्छे डिजाइन के बजाय इतिहास की दुर्घटना की तरह लगता है।
एरिक लिपर्ट

जवाबों:


118

सबसे पहले, मैं कहूंगा कि आप जिस लिंक को लिंक करते हैं, वह उस विशेष मुद्दे को खत्म कर देता है और वैश्विक राज्य की प्राथमिक बुराई यह है कि यह अप्रत्याशित तरीके से युग्मन का परिचय देता है जिससे भविष्य में आपके सिस्टम के व्यवहार को बदलना मुश्किल हो सकता है।

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

  • ऑब्जेक्ट-ओरिएंटेड सिस्टम किसी ऑब्जेक्ट को ऑब्जेक्ट के एक अलग वर्ग के साथ बदलने की अनुमति देता है, जब तक कि यह मूल प्रकार का एक उपप्रकार है। यह व्यवहार को बदलने की अनुमति देता है , न कि केवल डेटा

  • एक आवेदन में वैश्विक राज्य आमतौर पर एक मजबूत स्थिरता की गारंटी नहीं देता है जो एक डेटाबेस करता है - कोई लेनदेन नहीं है जिसके दौरान आप इसके लिए एक सुसंगत स्थिति देखते हैं, कोई परमाणु अद्यतन नहीं करते हैं, आदि।

इसके अतिरिक्त, हम डेटाबेस स्टेट को एक आवश्यक बुराई के रूप में देख सकते हैं; इसे हमारे सिस्टम से खत्म करना असंभव है। वैश्विक राज्य, हालांकि, अनावश्यक है। हम इसे पूरी तरह से खत्म कर सकते हैं। यहां तक ​​कि एक डेटाबेस के साथ मुद्दे भी खराब थे, हम अभी भी कुछ संभावित समस्याओं को खत्म कर सकते हैं और एक आंशिक समाधान बिना समाधान के बेहतर है।


44
मुझे लगता है कि निरंतरता का बिंदु वास्तव में मुख्य कारण है: जब वैश्विक चर का उपयोग कोड में किया जाता है, तो आमतौर पर कोई भी नहीं बता रहा है कि वे वास्तव में आरंभिक हैं। मॉड्यूल के बीच निर्भरता कॉल के अनुक्रम के अंदर गहराई से छिपी हुई है, और दो सामानों की अदला-बदली की तरह सरल सामान वास्तव में गंदा कीड़े पैदा कर सकता है क्योंकि अचानक कुछ वैश्विक चर को अब सही ढंग से आरंभ नहीं किया जाता है जब यह पहली बार उपयोग किया जाता है। कम से कम यही वह समस्या है जिसकी मुझे विरासत कोड के साथ काम करने की आवश्यकता है, और जो एक बुरे सपने को दूर करती है।
सेमीस्टर

24
@ डेविडविमेन ने वास्तव में एक ऑनलाइन गेम के लिए विश्व-राज्य सिमुलेशन पर काम किया है, जो स्पष्ट रूप से उस एप्लिकेशन की श्रेणी में है जिसके बारे में आप बात कर रहे हैं, और यहां तक ​​कि मैं इसके लिए वैश्विक राज्य का उपयोग नहीं करेगा (और नहीं)। भले ही वैश्विक राज्य का उपयोग करके कुछ दक्षता हासिल की जा सकती है, लेकिन मुद्दा यह है कि वैश्विक राज्य स्केलेबल नहीं है । एक बार जब आप एकल-थ्रेडेड से बहु-थ्रेडेड आर्किटेक्चर में जाते हैं तो इसका उपयोग करना मुश्किल हो जाता है । जब आप NUMA आर्किटेक्चर में जाते हैं तो यह अक्षम हो जाता है । जब आप किसी वितरित आर्किटेक्चर में जाते हैं तो यह असंभव हो जाता है । कागज से आप तारीखों का हवाला देते हैं ...
जूल्स

24
1993. ये समस्याएं तब एक मुद्दे से कम थीं। लेखक एक सिंगल प्रोसेसर सिस्टम पर काम कर रहे थे, जिसमें 1,000 वस्तुओं की परस्पर क्रिया थी। एक आधुनिक प्रणाली में आप संभवतः उस तरह के सिमुलेशन को बहुत कम से कम दोहरे कोर सिस्टम पर चलाएंगे, लेकिन संभावना है कि यह एकल प्रणाली में कम से कम 6 कोर हो सकता है। अभी भी बड़ी समस्याओं के लिए, आप इसे एक क्लस्टर पर चलाएंगे। इस तरह के बदलाव के लिए, आपको वैश्विक स्थिति से बचना चाहिए क्योंकि वैश्विक स्थिति को प्रभावी रूप से साझा नहीं किया जा सकता है।
जूल्स

19
मुझे लगता है कि डेटाबेस स्टेट को "आवश्यक बुराई" कहना थोड़ा खिंचाव है। मेरा मतलब है, जब से राज्य बुराई बन गया? राज्य एक डेटाबेस का संपूर्ण उद्देश्य है। राज्य की जानकारी है। राज्य के बिना, आपके पास सभी ऑपरेटर हैं। कुछ को संचालित करने के लिए ऑपरेटरों के बिना क्या अच्छा है? उस राज्य को कहीं जाना है। दिन के अंत में, कार्यात्मक प्रोग्रामिंग एक अंत का एक साधन है और राज्य के बिना उत्परिवर्तित करने के लिए कुछ भी करने का कोई मतलब नहीं होगा। यह केक को आवश्यक बुराई कहने वाले बेकर की तरह एक सा है - यह बुराई नहीं है। यह पूरी बात है।
जे ...

5
@David Hammen "अभी भी कुछ ऐसी वस्तु है जो खेल में प्रत्येक वस्तु के बारे में कम से कम थोड़ा सा जानती है" जरूरी नहीं कि सच हो। आधुनिक वितरित सिमुलेशन में एक प्रमुख तकनीक स्थानीयता का लाभ उठा रही है और इस तरह के अनुमान लगा रही है कि दूर की वस्तुओं को दूर की हर चीज के बारे में जानने की जरूरत नहीं है, केवल उन दूर की वस्तुओं के मालिकों द्वारा उन्हें क्या डेटा प्रदान किया जाता है।
JAB

75

सबसे पहले, वैश्विक चर के साथ क्या समस्याएं हैं, जो आपके द्वारा जुड़े प्रश्न के स्वीकृत उत्तर के आधार पर हैं?

बहुत संक्षेप में, यह कार्यक्रम की स्थिति को अप्रत्याशित बनाता है।

डेटाबेस, समय के विशाल बहुमत, ACID के अनुरूप हैं। ACID विशेष रूप से अंतर्निहित मुद्दों को संबोधित करता है जो डेटा स्टोर को अप्रत्याशित या अविश्वसनीय बना देगा।

इसके अलावा, वैश्विक राज्य आपके कोड की पठनीयता पर चोट करता है।

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

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

डेटाबेस आमतौर पर शुरू करने के लिए वैश्विक चर की तुलना में अलग-अलग डेटा को मॉडल करते हैं, लेकिन एक पल के लिए इसे छोड़कर, डेटाबेस को ग्राउंड-अप से एक एसीआईडी-अनुपालन डेटा स्टोर बनाया जाता है जो वैश्विक चर के साथ कई चिंताओं को कम करता है।


4
+1 जो आप कह रहे हैं कि डेटाबेस में लेन-देन होता है, जिससे वैश्विक राज्य के कई टुकड़ों को पढ़ना और लिखना संभव होता है । अच्छी बात है, जिसे केवल प्रत्येक पूरी तरह से स्वतंत्र जानकारी के लिए वैश्विक चर का उपयोग करके देखा जा सकता है ।
l0b0

1
@ l0b0 लेनदेन एक ऐसा तंत्र है जो ACID के अधिकांश लक्ष्यों को प्राप्त करता है, सही है। लेकिन डीबी इंटरफ़ेस डेटा को अधिक स्थानीय दायरे में लाकर कोड को स्पष्ट करता है। JDBC RecordSet को कोशिश-के-संसाधन ब्लॉक या ORM फ़ंक्शन के साथ उपयोग करने के बारे में सोचें, जो एकल फ़ंक्शन कॉल का उपयोग करके डेटा का एक टुकड़ा प्राप्त करता है। इसकी तुलना उस डेटा के प्रबंधन से करें, जो आप कहीं वैश्विक स्तर पर पढ़ रहे हैं।

1
इसलिए वैश्विक चर का उपयोग करना ठीक होगा यदि मैं फ़ंक्शन की शुरुआत में एक स्थानीय चर (म्यूटेक्स के साथ) के मूल्य को कॉपी करता हूं, स्थानीय चर को संशोधित करता हूं, और फिर मूल्य को वैश्विक चर पर वापस कॉपी करता हूं कार्यक्रम? (... उन्होंने बयानबाजी से पूछा।)
आरएम

1
@ आरएम उन्होंने दो बिंदुओं का उल्लेख किया। आप जो फेंक चुके हैं वह पहले (प्रोग्राम स्टेट अप्रत्याशित) को संबोधित कर सकता है, लेकिन यह दूसरा (आपके कोड की पठनीयता) को संबोधित नहीं करता है। वास्तव में, यह आपके कार्यक्रम की पठनीयता को और भी बदतर बना सकता है: पी।
रिवालक

1
@RM आपका फंक्शन लगातार चलेगा, हाँ। लेकिन फिर आपके मन में यह सवाल आएगा कि क्या इस बीच में वैश्विक चर को कुछ और संशोधित किया गया था, और यह कि आप इसे लिख रहे हैं, उससे अधिक महत्वपूर्ण था। डेटाबेस में भी यही समस्या हो सकती है।
ग्राहम

45

मैं कुछ टिप्पणियों की पेशकश करेगा:

हाँ, एक डेटाबेस वैश्विक स्थिति है।

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

वैश्विक चर का उपयोग करने के संभावित परिणामों में से एक यह है कि दो अलग-अलग "मॉड्यूल" अपने अलग-अलग उद्देश्यों के लिए उस चर का उपयोग करेंगे। और उस हद तक, एक डेटाबेस तालिका अलग नहीं है। यह उसी समस्या का शिकार हो सकता है।

हम्म ... यहाँ बात है:

यदि कोई मॉड्यूल किसी तरह से बाहरी रूप से काम नहीं करता है, तो यह कुछ भी नहीं करता है।

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

अब, हमारी प्राथमिकता डेटा प्राप्त करना और डेटा वापस करना है। अधिकांश मॉड्यूल केवल यह लिखना आसान है कि क्या वे बाहरी दुनिया के लिए नापसंद के साथ लिखे जा सकते हैं। लेकिन अंततः, कुछ को डेटा खोजने और उस बाहरी, वैश्विक स्थिति को संशोधित करने की आवश्यकता होती है ।

इसके अलावा, वास्तविक दुनिया के अनुप्रयोगों में, डेटा मौजूद है ताकि इसे विभिन्न कार्यों द्वारा पढ़ा और अपडेट किया जा सके । कुछ मुद्दों को ताले और लेनदेन द्वारा रोका जाता है। लेकिन, इन कार्यों को सिद्धांत रूप में एक-दूसरे के साथ संघर्ष से रोकना, दिन के अंत में, बस सावधानीपूर्वक सोच शामिल है (और गलतियाँ करते हुए ...)

लेकिन यह भी, हम आम तौर पर सीधे वैश्विक राज्य के साथ काम नहीं कर रहे हैं

जब तक एप्लिकेशन डेटा लेयर (SQL या जो भी हो) में रहता है, तब तक हमारे मॉड्यूल जिन वस्तुओं के साथ काम करते हैं, वे वास्तव में साझा वैश्विक स्थिति की एक प्रति हैं। हम वास्तविक, साझा राज्य के लिए जो भी प्रभाव चाहते हैं, हम कर सकते हैं

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

और अंत में, हम आमतौर पर डेटाबेस के साथ अलग-अलग चीजें करते हैं, जितना कि हम शरारती ग्लोबल्स के साथ कर सकते हैं

एक शरारती, टूटी हुई वैश्विक शक्ल इस तरह है:

Int32 counter = 0;

public someMethod() {
  for (counter = 0; counter < whatever; counter++) {
    // do other stuff.
  }
}

public otherMethod() {
  for (counter = 100; counter < whatever; counter--) {
    // do other stuff.
  }
}

हम उस तरह की प्रक्रिया / परिचालन सामग्री के लिए डेटाबेस का उपयोग नहीं करते हैं। और यह डेटाबेस की धीमी प्रकृति और एक सरल चर की सापेक्ष सुविधा हो सकती है जो हमें रोकती है: डेटाबेस के साथ हमारी सुस्त, अजीब बातचीत बस उन्हें कई गलतियों के लिए बुरा उम्मीदवार बनाती है जो हमने ऐतिहासिक रूप से चर के साथ बनाया है।


3
डेटाबेस में गारंटी देने का तरीका (क्योंकि हम यह नहीं मान सकते हैं) "कि जो डेटा हमें नहीं दिया गया है" एक लेनदेन होगा।
l0b0

हाँ ... कि "समान-लॉकिंग के समान" के साथ निहित होना चाहिए था।
svidgen

लेकिन, दिन के अंत में ध्यान से सोचना मुश्किल हो सकता है।

हां, डेटाबेस वास्तव में वैश्विक स्थिति है - यही कारण है कि यह कुछ भी जैसे git या ipfs का उपयोग करके डेटा साझा करने के लिए बहुत लुभावना है।
विलियम पायने

21

मैं मूलभूत दावे से असहमत हूं कि:

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

मेरा प्रारंभिक विचार था "वाह। बस वाह"। इतना समय और प्रयास बिल्कुल इसी से बचने की कोशिश करने में बिताया जाता है - और प्रत्येक आवेदन के लिए व्यापार-समझौते और समझौते से क्या काम होता है। सिर्फ अनदेखी करने के लिए यह आपदा का एक नुस्खा है।

लेकिन मैं एक वास्तुशिल्प स्तर पर भी डायसिस करता हूं। एक वैश्विक चर सिर्फ वैश्विक स्थिति नहीं है। यह वैश्विक स्थिति है जो पारदर्शी रूप से कहीं से भी सुलभ है। एक डेटाबेस का उपयोग करने के विपरीत आपको इसके लिए एक संभाल की आवश्यकता होती है - (जब तक कि आप एक वैश्विक चर में हैंडल की तुलना में संग्रहीत नहीं करते हैं ...)

उदाहरण के लिए, वैश्विक वैरिएबल का उपयोग इस तरह हो सकता है

int looks_ok_but_isnt() {
  return global_int++;
}

int somewhere_else() {
  ...
  int v = looks_ok_but_isnt();
  ...
}

लेकिन एक डेटाबेस के साथ एक ही काम करने से इसके बारे में अधिक स्पष्ट होना होगा कि यह क्या कर रहा है

int looks_like_its_using_a_database( MyDB * db ) {
   return db->get_and_increment("v");
}

int somewhere_else( MyBD * db ) { 
   ...
   v = looks_like_its_using_a_database(db);
   ...
}

डेटाबेस एक जाहिर है एक डेटाबेस के साथ mucking है। यदि आप डेटाबेस का उपयोग नहीं करना चाहते हैं, तो आप स्पष्ट स्थिति का उपयोग कर सकते हैं और यह डेटाबेस केस के समान ही दिखता है।

int looks_like_it_uses_explicit_state( MyState * state ) {
   return state->v++;
}


int somewhere_else( MyState * state ) { 
   ...
   v = looks_like_it_uses_explicit_state(state);
   ...
}

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


2
हाँ, मुझे लगा कि यह दिलचस्प था जब ओपी ने कहा: " आपको परवाह नहीं है कि डेटा क्या है? यह पूरी बात है " - अगर हम परवाह नहीं करते हैं, तो इसे क्यों स्टोर करें? यहाँ एक विचार है: चलो बस चर और डेटा का उपयोग बिल्कुल बंद कर दें । यह चीजों को बहुत सरल बनाना चाहिए। "दुनिया को रोको, मैं जाना चाहता हूं!"

1
+1 एक ही डेटाबेस से अलग-अलग थ्रेड या ऐप लिखना और पढ़ना बड़ी संख्या में जानी-मानी समस्याओं का एक संभावित स्रोत है, यही वजह है कि डेटाबेस या ऐप स्तर पर या तो इससे निपटने के लिए हमेशा एक रणनीति होनी चाहिए, या दोनों। तो यह निश्चित रूप से सच नहीं है कि आप (ऐप डेवलपर) इस बात की परवाह नहीं करते हैं कि कौन डेटाबेस से पढ़ रहा है या लिख ​​रहा है।
एंड्रेस एफ

1
+1 साइड नोट पर, यह उत्तर बहुत अधिक बताता है कि मैं निर्भरता इंजेक्शन के बारे में सबसे ज्यादा नफरत करता हूं। यह इस प्रकार की निर्भरता को छुपाता है।
jpmc26

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

2
@EmilLundberg नहीं, समस्या तब है जब आपके पास एक पदानुक्रम है। निर्भरता इंजेक्शन उच्चतर स्तरों में कोड से निचले स्तरों की निर्भरता को छुपाता है, जिससे चीजों का ट्रैक रखना मुश्किल हो जाता है। उदाहरण के लिए, यदि यह MakeNewThingनिर्भर करता है MakeNewThingInDbऔर मेरा नियंत्रक वर्ग उपयोग करता है MakeNewThing, तो यह मेरे नियंत्रक के कोड से स्पष्ट नहीं है कि मैं डेटाबेस को संशोधित कर रहा हूं। तो फिर क्या होगा यदि मैं एक अन्य वर्ग का उपयोग करता हूं जो वास्तव में मेरे वर्तमान लेनदेन को डीबी से जोड़ता है? DI किसी वस्तु के दायरे को नियंत्रित करना बहुत कठिन बनाता है।
jpmc26

18

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

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

उदाहरण के लिए:

  • डेटाबेस आमतौर पर प्रकार और संरचना सत्यापन में निर्मित होते हैं जो उन्हें एक्सेस करने वाली भाषा से आगे जाते हैं
  • डेटाबेस लगभग सर्वसम्मति से लेनदेन के आधार पर अपडेट करते हैं, जो असंगत राज्यों को रोकता है, जहां कोई गारंटी नहीं है कि अंत राज्य एक वैश्विक ऑब्जेक्ट में कैसा दिखेगा (जब तक कि यह एक सिंगलटन के पीछे छिपा हुआ है)
  • डेटाबेस संरचना कम से कम अंतर्निहित तालिका या ऑब्जेक्ट संरचना के आधार पर प्रलेखित है, इसका उपयोग करने वाले एप्लिकेशन की तुलना में अधिक-इसलिए

सबसे महत्वपूर्ण बात यह है कि, डेटाबेस एक वैश्विक चर की तुलना में एक अलग उद्देश्य की सेवा करते हैं। डेटाबेस बड़ी मात्रा में संगठित डेटा के भंडारण और खोज के लिए हैं, जहां वैश्विक चर विशिष्ट niches (जब उचित) की सेवा करते हैं।


1
हुह। आपने मुझे लगभग हरा दिया, जबकि मैं लगभग समान उत्तर लिखने के माध्यम से आधा था। :)
जूल्स

@ आपका जवाब आपके आवेदन की चीजों के विवरण से अधिक विवरण प्रदान करता है; इसे रखें।
जेफरी स्वीनी

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

यदि आप जावा जैसी स्थिर-टाइप भाषा का उपयोग कर रहे हैं, तो अंक 1 और 3 अभी भी लागू हैं?
जेसविन जोस

@aitchnyu जरूरी नहीं। मुद्दा यह है कि डेटाबेस को डेटा को साझा करने के उद्देश्य से बनाया जाता है, जहां वैश्विक चर आमतौर पर नहीं होते हैं। सख्त भाषा में सेल्फ-डॉक्यूमेंटिंग इंटरफेस को लागू करने वाली वस्तु भी एक ढीली टाइप की गई NoSQL डेटाबेस की तुलना में एक अलग उद्देश्य प्रदान करती है।
जेफरी स्वीनी

10

लेकिन जब मैं उस पर गौर करता हूं, तो मैं मदद नहीं कर सकता, लेकिन लगता है कि यह वास्तव में कमजोर व्याख्या है, क्योंकि यह कैसे डेटाबेस में संग्रहीत डेटा के साथ काम करने से अलग है?

या किसी इंटरएक्टिव डिवाइस के साथ काम करने से अलग, किसी फ़ाइल के साथ, साझा की गई मेमोरी आदि के साथ। एक प्रोग्राम जो हर बार एक ही काम करता है वह बहुत ही उबाऊ और बेकार प्रोग्राम है। तो हाँ, यह एक कमजोर तर्क है।

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

दूसरी ओर, वैश्विक चर के साथ, यह बिल्कुल स्पष्ट नहीं है। एपीआई कॉल करने के लिए कहता है foo(this_argument, that_argument)। कॉलिंग सीक्वेंस में ऐसा कुछ नहीं है जो कहता हो कि ग्लोबल वैरिएबल g_DangerWillRobinsonको कुछ वैल्यू पर सेट किया जाना चाहिए लेकिन कॉल करने से पहले foo(या कॉल करने के बाद जांच की गई foo)।


Google ने मुख्य रूप से C ++ में गैर-कास्ट संदर्भ तर्कों के उपयोग पर प्रतिबंध लगा दिया क्योंकि यह उस कोड के पाठक के लिए स्पष्ट नहीं है जो foo(x)बदल जाएगा xक्योंकि यह fooएक तर्क के रूप में एक गैर-निरंतर संदर्भ लेता है। (C # के साथ तुलना करें, जो यह निर्धारित करता है कि फ़ंक्शन परिभाषा और कॉल साइट दोनों को refकीवर्ड के साथ एक संदर्भ पैरामीटर योग्य होना चाहिए ।) जबकि मैं इस पर Google मानक से सहमत नहीं हूं, मुझे उनकी बात समझ में नहीं आती है।

कोड एक बार लिखा जाता है और कुछ बार संशोधित किया जाता है, लेकिन यदि यह बिल्कुल अच्छा है, तो इसे कई बार पढ़ा जाता है। संचार की छिपी हुई रेखाएं बहुत बुरे कर्म हैं। C ++ का गैर-कॉन्स्टेंस संदर्भ संचार की एक छोटी छिपी रेखा का प्रतिनिधित्व करता है। एक अच्छा एपीआई या एक अच्छा आईडीई मुझे दिखाएगा कि "ओह! यह संदर्भ द्वारा कॉल है।" वैश्विक चर संचार की एक बड़ी छिपी हुई रेखा है।


आपका जवाब अधिक समझ में आता है।
बिलल बेगेरजाद

8

मुझे लगता है कि उद्धृत स्पष्टीकरण मुद्दे को उस बिंदु तक पहुँचा देता है जहाँ तर्क हास्यास्पद हो जाता है। बेशक, बाहरी डेटाबेस की स्थिति वैश्विक राज्य में योगदान करती है। महत्वपूर्ण सवाल यह है कि कैसेआपका कार्यक्रम वैश्विक स्थिति पर (परस्पर) निर्भर करता है। यदि एक पुस्तकालय का कार्य श्वेत-स्थान पर तारों को विभाजित करने के लिए एक डेटाबेस में संग्रहीत मध्यस्थ परिणामों पर निर्भर करेगा, तो मैं इस डिजाइन पर कम से कम उतना ही आपत्ति जताऊंगा, जितना कि मैं उसी उद्देश्य के लिए उपयोग किए जाने वाले वैश्विक चरित्र सरणी पर आपत्ति करूंगा। दूसरी ओर, यदि आप तय करते हैं कि आपके आवेदन को इस बिंदु पर व्यावसायिक डेटा संग्रहीत करने के लिए पूर्ण-विकसित DBMS की आवश्यकता नहीं है और एक वैश्विक इन-मेमोरी की-वैल्यू संरचना करेगी, तो यह आवश्यक रूप से खराब डिज़ाइन का संकेत नहीं है। जो महत्वपूर्ण है वह यह है कि - कोई फर्क नहीं पड़ता कि आप अपने डेटा को संग्रहीत करने के लिए क्या समाधान चुनते हैं - यह विकल्प सिस्टम के बहुत छोटे हिस्से में अलग-थलग है, इसलिए अधिकांश घटक अलगाव में तैनात और यूनिट-परीक्षण के समाधान के लिए अज्ञेय हो सकते हैं और तैनात किए गए थोड़े प्रयास से बाद के समय में समाधान को बदला जा सकता है।


8

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

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

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

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


7

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

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

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

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

यह हिस्सा, वह क्षण जहां एक वैश्विक चर एक छिपी हुई निर्भरता बन जाता है, जिसे प्रोग्रामर द्वारा बुराई माना जाता है। यह कोड के बारे में तर्क करना कठिन बनाता है, यह भविष्यवाणी करना कठिन है कि यह कैसे व्यवहार करेगा, पुन: उपयोग करने के लिए कठिन, कठिन परीक्षण और विशेष रूप से, यह डिबग बढ़ाता है और समस्या होने पर समय को ठीक करता है।

ऐसा ही तब होता है जब हम डेटाबेस पर निर्भरता छिपाते हैं। हमारे पास डेटाबेस क्वेरीज़ और कमांड के लिए सीधे कॉल करने वाले फ़ंक्शन या ऑब्जेक्ट हो सकते हैं, इन निर्भरताओं को छिपा सकते हैं और हमें वही परेशानी पैदा कर सकते हैं जो वैश्विक चर का कारण बनते हैं; या हम उन्हें स्पष्ट कर सकते हैं, जो, जैसा कि यह पता चलता है, एक सर्वोत्तम अभ्यास माना जाता है जो कई नामों से जाता है, जैसे कि रिपॉजिटरी पैटर्न, डेटा-स्टोर, गेटवे, आदि।

पुनश्च: ऐसे अन्य पहलू हैं जो इस तुलना के लिए महत्वपूर्ण हैं, जैसे कि क्या संगामिति शामिल है, लेकिन वह बिंदु यहां अन्य उत्तरों द्वारा कवर किया गया है।


मुझे यह पसंद है कि आपने इसे निर्भरता के कोण से लिया है।
कोबजार

6

ठीक है, चलो ऐतिहासिक बिंदु से शुरू करते हैं।

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

क्या इसका मतलब यह है कि वैश्विक परिवर्तनशील नफरत अतीत की बात है? काफी नहीं।

सबसे पहले, मुझे यह उल्लेख करना होगा कि जिस परियोजना पर मैं अभी काम कर रहा हूँ , उसमें तर्कों को पारित करने के लिए मैंने वही दृष्टिकोण देखा है । C # में दो संदर्भ प्रकार के उदाहरणों को पारित करने के लिए, एक परियोजना में जो लगभग 10 साल पुरानी है। इसका शाब्दिक अर्थ इस तरह से करने का कोई अच्छा कारण नहीं है, और यह संभवत: कार्गो-कल्टिंग या सी # काम करने की पूरी गलतफहमी से पैदा हुआ है।

इससे भी बड़ी बात यह है कि वैश्विक चर जोड़कर, आप हर एक ऐसे कोड के दायरे का विस्तार कर रहे हैं, जिसकी पहुंच उस वैश्विक चर तक है। उन सभी सिफारिशों को याद रखें जैसे "अपने तरीके कम रखें"? यदि आपके पास 600 वैश्विक चर (फिर से, वास्तविक-विश्व उदाहरण: /) हैं, तो आपके सभी विधि स्कोपों ​​का उन 600 वैश्विक चर द्वारा विस्तार किया गया है, और इसका कोई सरल तरीका नहीं है कि किसके पास पहुंच है।

यदि गलत (सामान्य तरीके से :)) किया जाता है, तो वैश्विक चर एक दूसरे के बीच युग्मन हो सकते हैं। लेकिन आपको पता नहीं है कि वे कैसे युग्मित हैं, और यह सुनिश्चित करने के लिए कोई तंत्र नहीं है कि वैश्विक स्थिति हमेशा सुसंगत है। यहां तक ​​कि अगर आप चीजों को सुसंगत रखने और रखने के लिए महत्वपूर्ण खंडों का परिचय देते हैं, तो आप पाएंगे कि यह खराब तरीके से एक उचित ACID डेटाबेस से तुलना करता है:

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

क्या इन मुद्दों को हल करना संभव है? ज़रुरी नहीं। आपको इसे संभालने के लिए एन्कैप्सुलेशन की आवश्यकता है, या वास्तव में सख्त अनुशासन। यह सही करना मुश्किल है, और यह आमतौर पर सॉफ्टवेयर विकास में सफलता के लिए बहुत अच्छा नुस्खा नहीं है :)

छोटे दायरे के बारे में कारण के लिए कोड आसान बनाने के लिए जाता है। वैश्विक चर भी कोड के सबसे सरल टुकड़ों में गुंजाइश के विशाल swathes शामिल बनाते हैं।

बेशक, इसका मतलब यह नहीं है कि ग्लोबल स्कूपिंग बुराई है। यह सिर्फ आपके लिए जाने वाला पहला समाधान नहीं होना चाहिए - यह "लागू करने के लिए सरल, बनाए रखने के लिए कठिन" का एक विशिष्ट उदाहरण है।


भौतिक दुनिया की तरह बहुत कुछ लगता है: चीजों को वापस रोल करना बहुत कठिन है।

यह एक अच्छा जवाब है, लेकिन यह शुरुआत में एक थीसिस स्टेटमेंट (टीएल; डीआर सेक्शन) खड़ा कर सकता है।
jpmc26

6

एक वैश्विक चर एक उपकरण है, इसका उपयोग अच्छे और बुरे के लिए किया जा सकता है।

एक डेटाबेस एक उपकरण है, इसका उपयोग अच्छे और बुरे के लिए किया जा सकता है।

मूल पोस्टर नोट्स के रूप में, अंतर यह सब बड़ा नहीं है।

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

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

यदि लोग ACID दृष्टिकोण का उपयोग वैश्विक चर के लिए करते हैं, तो वे इतने बुरे नहीं होंगे।

दूसरी ओर, यदि आप डेटाबेस को बुरी तरह से डिज़ाइन करते हैं, तो वे बुरे सपने हो सकते हैं।


3
स्टैकओवरफ़्लो पर विशिष्ट छात्र का दावा: मेरी मदद करो! मेरा कोड एकदम सही है, लेकिन यह सही काम नहीं कर रहा है!
डेविड हैमेन

"ग्लोबल वैरिएबल्स के लिए ACID दृष्टिकोण" - क्लोजर में देखें।
चार्ल्स डफी

@ डेविडविमेन और आपको लगता है कि पेशेवर छात्रों के विपरीत एक मस्तिष्क है?
बिलाल बेगेरदज

@BillalBEGUERADJ - यह पेशेवरों और छात्रों के बीच अंतर है। हम जानते हैं कि वर्षों के अनुभव और कोड समीक्षा, परीक्षण आदि के सर्वोत्तम प्रयासों के बावजूद, हमारा कोड सही नहीं है।
डेविड हैमेन


5

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


3
उदाहरण के लिए, errnoसी। में
डेविड हैमेन

1
यह बताता है कि ग्लोबल्स और डेटाबेस समान क्यों नहीं हैं। अन्य अंतर हो सकते हैं लेकिन आपकी विशिष्ट पोस्ट पूरी तरह से अवधारणा को नष्ट कर देती है। यदि आपने एक त्वरित कोड उदाहरण दिया है, तो मुझे यकीन है कि आपको बहुत सारे upvotes मिलेंगे। जैसे MyFunc () {x = globalVar * 5; // .... कुछ अन्य प्रसंस्करण; y = globalVar * 34; // ओओओप्स, कुछ अन्य थ्रेड ग्लोबलवर्कर बदल सकते हैं कुछ अन्य प्रसंस्करण के दौरान और x और y अपनी गणना में GlobalVar के लिए विभिन्न मूल्यों का उपयोग कर रहे हैं, जो निश्चित रूप से वांछनीय परिणाम नहीं देंगे।
डंक

5

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

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

ठीक वही बात ** डेटाबेस पर लागू होती है, जो वैश्विक स्थिति है - जैसे वैश्विक चर हैं। यदि आप डेटाबेस तक पहुँच के बिना कर सकते हैं, और परिणामी तर्क आपको सभी की आवश्यकता है और समान रूप से जटिल है, तो डेटाबेस का उपयोग करने से आपकी परियोजना के लिए जोखिम बढ़ जाता है, वह भी बिना किसी लाभ के।

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


* यहां अपवाद छात्र हैं। यह समझ में आता है कि छात्रों को वैश्विक चर का उपयोग करने से रोकना है, इसलिए उन्हें सीखना होगा कि विकल्प क्या हैं।

** कुछ जवाब गलत तरीके से दावा करते हैं कि डेटाबेस किसी तरह वैश्विक राज्य के अन्य रूपों की तुलना में बेहतर संरक्षित हैं (प्रश्न स्पष्ट रूप से वैश्विक राज्य के बारे में है , न कि केवल वैश्विक चर)। वह बोलबाला है। डेटाबेस परिदृश्य में दी जाने वाली प्राथमिक सुरक्षा कन्वेंशन द्वारा होती है, जो कि किसी भी अन्य वैश्विक स्थिति के लिए बिल्कुल समान है। अधिकांश भाषाएं वैश्विक राज्य के लिए बहुत अधिक अतिरिक्त सुरक्षा की अनुमति देती हैं const, उन वर्गों के रूप में , जो निर्माणकर्ता में सेट होने के बाद बस अपने राज्य को बदलने की अनुमति नहीं देते हैं, या गेटर्स और सेटर्स जो थ्रेड जानकारी या प्रोग्राम स्टेट को ध्यान में रख सकते हैं।


2

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

वे यहाँ महत्वपूर्ण अंतर एक महत्वपूर्ण जिम्मेदारी है।

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

एक ही धारणा व्यापक स्तर पर ग्लोबल्स वी / एस डेटाबेस पर लागू होती है। साथ ही, प्रोग्रामिंग लैंग्वेज / इकोसिस्टम निजी v / s पब्लिक पर एक्सेस प्रतिबंधों की गारंटी देता है, क्योंकि यह उन पर लागू होता है (स्मृति रद्द) ग्लोबल्स v / s डेटाबेस।

जब मल्टीथ्रेडिंग खेल में आता है, तो निजी v / s सार्वजनिक v / s वैश्विक v / s डेटाबेस की अवधारणा एक स्पेक्ट्रम के साथ केवल भेद है।

static int global; // within process memory space
static int dbvar; // mirrors/caches data outside process memory space

class Cls {
    public: static int class_public; // essentially the same as global
    private: static int class_private; // but public to all methods in class

    private: static void method() {
        static int method_private; // but public to all scopes in method
        // ...
        {
            static int scope1_private; // mutex guarded
            int the_only_truly_private_data;
        }
        // ...
        {
            static int scope2_private; // mutex guarded
        }
    }
}

1

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

वैश्विक चर की तरह, एक डेटाबेस में मूल्य (एस) को अनलॉक होने के बाद बदल दिया जा सकता है, लेकिन पहुंच को नियंत्रित करने के कई तरीके हैं (डेटा को बदलने की अनुमति दी गई सभी देवियों को खाते में पासवर्ड न दें।)। यदि आपके पास एक चर है जिसमें सीमित पहुंच है, तो यह बहुत वैश्विक नहीं है।


0

कई अंतर हैं:

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

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

  • वैश्विक चर तेज हैं । डेटाबेस से कुछ प्राप्त करने के लिए डेटाबेस कनेक्शन की आवश्यकता होती है, मेरे लिए चयन करें और फिर डेटाबेस कनेक्शन बंद होना चाहिए। किसी भी प्रकार के रूपांतरणों की आपको आवश्यकता हो सकती है। तुलना करें कि आपके कोड में एक वैश्विक एक्सेस किया जा रहा है।

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


0

बेशक ग्लोबल्स हमेशा अनुपयुक्त नहीं होते हैं। वे मौजूद हैं क्योंकि उनका एक वैध उपयोग है। ग्लोबल्स के साथ मुख्य समस्या, और उनसे बचने के लिए चेतावनी का प्राथमिक स्रोत, वह कोड जो एक वैश्विक का उपयोग करता है, वह एक और केवल एक वैश्विक से जुड़ा होता है।

उदाहरण के लिए, एक HTTP सर्वर पर सर्वर नाम को संग्रहीत करने पर विचार करें।

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

इसके विपरीत, यदि सर्वर का नाम डेटाबेस में है, तो कोई समस्या नहीं है। आप HTTP डेटाबेस के प्रत्येक उदाहरण के लिए बस उस डेटाबेस का एक उदाहरण बना सकते हैं। क्योंकि सर्वर के प्रत्येक उदाहरण का डेटाबेस का अपना उदाहरण होता है, इसका अपना सर्वर नाम हो सकता है।

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


0

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

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

तो सवाल यह है कि कैसे डेटाबेस ग्लोबल्स से अलग है, इन दो पहलुओं के बीच द्विभाजित है। क्या वे युग्मन का परिचय देते हैं? हां, वे कर सकते हैं लेकिन यह बहुत कुछ इस बात पर निर्भर करता है कि एप्लिकेशन को कैसे डिज़ाइन किया गया है और डेटाबेस को कैसे डिज़ाइन किया गया है। डेटाबेस के डिजाइन के विवरण के बिना वैश्विक युग्मन का परिचय देना है या नहीं, इसका एक ही उत्तर देने के लिए कई कारक हैं। जैसे कि क्या वे राज्य के बंटवारे का परिचय देते हैं, ठीक है, यह एक डेटाबेस का मुख्य बिंदु है। सवाल यह है कि क्या वे इसे अच्छी तरह से करते हैं। फिर से, मुझे लगता है कि बहुत सी अन्य जानकारी जैसे कि विकल्प और कई अन्य ट्रेड-ऑफ के बिना जवाब देना बहुत जटिल है।


0

मैं इसके बारे में थोड़ा अलग तरीके से सोचूंगा: "वैश्विक चर" जैसा व्यवहार डेटाबेस प्रशासक (डीबीए) द्वारा भुगतान किया गया मूल्य है क्योंकि यह उनके काम करने के लिए आवश्यक बुराई है।

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

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

डेटाबेस विकास उन अल्पसंख्यक आवाज स्थितियों में से एक है। डीबीए काम करने के लिए आवश्यक उपकरण बहुत शक्तिशाली हैं, और उनका सिद्धांत एनकैप्सुलेशन में निहित नहीं है। अपने डेटाबेस से प्रदर्शन के हर एक पल को बाहर निकालने के लिए, उन्हें ग्लोबल्स के समान हर चीज की पूर्ण अनफ़िट की आवश्यकता होती है। उनके खतरनाक 100 मिलियन रो (या अधिक!) डेटाबेसों में से एक को वेल्ड करें, और आप इस बात की सराहना करेंगे कि उन्होंने अपने DB इंजन को किसी भी छिद्र को पकड़ने नहीं दिया।

वे उसके लिए एक कीमत चुकाते हैं, एक प्रिय कीमत। डीबीए को उनके ध्यान में विस्तार के साथ लगभग रोगविज्ञानी होने के लिए मजबूर किया जाता है, क्योंकि उनके उपकरण उनकी रक्षा नहीं करते हैं। सुरक्षा के रास्ते में उनके पास सबसे अच्छा है ACID या शायद विदेशी चाबियां। जो पैथोलॉजिकल नहीं हैं वे खुद को तालिकाओं की पूरी गड़बड़ी के साथ पाते हैं जो पूरी तरह से अनुपयोगी हैं, या यहां तक ​​कि भ्रष्ट भी हैं।

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

क्या आप बल्कि टूटे हुए कांच पर, या अच्छी तरह से बहने वाले फुटपाथों पर घूम सकते हैं, यदि अन्य सभी चीजें समान हैं? हां, आप टूटे हुए कांच पर चल सकते हैं। हां, कुछ लोग इसे कर रहे हैं। लेकिन फिर भी, बस उन्हें फुटपाथ पर चढ़ने और आगे बढ़ने दें!


0

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

अंतर को मापना आसान है: क्या आप अपने प्रोग्राम लॉजिक के दो उदाहरणों को चला सकते हैं, प्रत्येक अपने स्वयं के डेटाबेस का उपयोग करके, कोड में आक्रामक परिवर्तन किए बिना एक ही कार्यक्रम / प्रक्रिया में? यदि हां, तो आपका डेटाबेस वास्तव में "वैश्विक स्थिति" नहीं है।


-2

ग्लोबल्स बुराई नहीं हैं; वे बस एक उपकरण हैं। ग्लोबल्स का MISUSE समस्याग्रस्त है, जैसा कि किसी अन्य प्रोग्रामिंग सुविधा का दुरुपयोग है।

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


अपने डाउनवोट्स को समझाते हुए कुछ डाउनवॉटर माइंड करेंगे? यह एक स्पष्टीकरण के बिना नीचे की ओर कठोर लगता है।
बायरन जोन्स

-2

केवल-पढ़ें पैटर्न, और मान लें कि जब आप इसे प्रिंट करते हैं तो आपका डेटा अद्यतित नहीं होता है। कतार दूसरे तरीके से लिखती है या संभालती है। नरक शैतान में आपका स्वागत है, आप वैश्विक db का उपयोग कर रहे हैं।

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