2008-12-13 9 views
31

डेस्कटॉप एप्लिकेशन के लिए है। यह सिर्फ एक सामान्य सवाल है कि शायद केवल सामान्य उत्तरों की आवश्यकता हो।ठीक है, वैश्विक चर की निंदा की जाती है, सिंगलटन तुच्छ है, विकल्प क्या है?

+1

मुझे खेद है कि यह बंद करने के लिए उम्मीदवार की तरह लगता है, जब तक कि आप इसे कहने के लिए नहीं बदलते कि आपका क्यू वास्तविकता क्या है –

+1

क्या मैंने कुछ गलत टाइप किया? क्षमा करें, मुझे समझ में नहीं आता कि आप यह प्रश्न क्यों बंद करना चाहते हैं। मैं बस इतना पूछ रहा था कि एक सामान्य प्रोग्रामिंग सवाल था। – mhd

+0

मुझे लगता है कि आपका प्रश्न ठीक है। यदि आप इसे बहुत सावधानी से नहीं पढ़ते हैं, तो यह थोड़ा विद्रोही लगता है ("निंदा" और "तुच्छ" उत्पन्न होने वाले शब्द), लेकिन आप वास्तव में सर्वोत्तम प्रथाओं के बारे में पूछ रहे हैं। – MusiGenesis

उत्तर

31

स्थिर डेटा सदस्यों के साथ एक स्थिर वर्ग? लेकिन कौन परवाह करता है। स्टेटिक डेटा सदस्य अधिक राजनीतिक रूप से सही पैकेजिंग के साथ वैश्विक चर हैं।

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

मान लीजिए कि आप सी/सी ++ का उपयोग कर रहे हैं, तो मैं अनुशंसा करता हूं कि आपके पास वैश्विक चर नहीं हैं जो कक्षा के उदाहरण हैं जो ढेर से स्मृति आवंटित करते हैं। वे आपके लिए मेमोरी लीक की जांच करने वाले टूल का उपयोग करना कठिन बना देंगे। ग्लोबल को एक सूचक के रूप में घोषित करें, इसे मुख्य() की शुरुआत में नया करें, इसे अंत में हटा दें।

6 टिप्पणियाँ के बाद संपादित करें: लॉगिंग के बारे में सोचें। क्या आप अपने ऐप में कहीं से भी अपने लॉग में एक लाइन लिखने में सक्षम नहीं होना चाहते हैं? आप कितना ठोस रूप से पूरा करते हैं कि लॉगिंग करने के लिए विश्व स्तर पर कुछ ऐसा दिखाई नहीं दे रहा है? यदि आप वैश्विक स्तर पर कुछ दिखाना चाहते हैं, तो आगे बढ़ें और इसे वैश्विक रूप से दृश्यमान बनाएं।

+0

.NET से आ रहा हूं मैं सहमत हूं - कक्षाओं के लिए स्थिर चर। यह आपके लिए वैश्विक चर के लिए एक अच्छा पर्याप्त संगठन प्रदान करता है। :) –

+0

फैशन? दशकों से वैश्विक चर की निंदा की गई है, और अच्छे कारणों से। लेकिन मैं मानता हूं कि सिंगलेट और कक्षा चर एक ही बात है। –

+1

यह ध्यान दिया जाना चाहिए कि स्थैतिक सदस्य वास्तव में उन समस्याओं को हल नहीं करते हैं जो ग्लोबल मौजूद हैं। ग्लोबल्स को बुरे के रूप में क्यों देखा जाता है, इसके कारण ज्यादातर स्थिर सदस्यों पर भी लागू होते हैं। –

2

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

0

इसका एक सामान्य समाधान एकलटन/वैश्विक चर के बजाय सिंगल-इंस्टेंस क्लास का उपयोग करना है।

यह सुनिश्चित करने के लिए आपका आवेदन ज़िम्मेदार होगा कि आपके पास केवल एक उदाहरण है।

यह समाधान थोडा बेकार है क्योंकि आप लोगों को अपनी कक्षा को कम करने से रोक नहीं सकते हैं (एक सिंगलटन नहीं है) इसलिए यह एक आंतरिक वर्ग होना चाहिए।

हालांकि मुझे सिंगलटन पैटर्न के बारे में सभी religious wars के बारे में बहुत अधिक परवाह नहीं है - अगर मुझे लगता है कि यह मेरी आवश्यकताओं के अनुरूप है तो मैं आमतौर पर इसका उपयोग करता हूं।

3

मुझे कोई परवाह नहीं है कि सिंगलटन या वैश्विक चर की अनुशंसा नहीं की जाती है। अगर मुझे ऐसा लगता है कि इसे लागू करने का सबसे तार्किक तरीका है तो मैं आगे बढ़ूंगा और इसका इस्तेमाल करूंगा।

0

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

1

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

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

8

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

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

इसी प्रकार, मैं आसानी से प्रतिक्रिया कर सकता हूं, क्योंकि ऑब्जेक्ट पर सीधे जो कुछ भी पारित किया गया है उसके अलावा कक्षाओं पर कोई जादू निर्भरता नहीं है।

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

+5

क्या आप प्रत्येक फ़ंक्शन, या उपयोगकर्ता भाषा, या सहायता फ़ाइल के स्थान पर लॉगिंग उदाहरण पास करना चाहते हैं ताकि यह संदर्भ संवेदनशील सहायता कर सके। –

+1

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

12

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

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

typedef struct Pnmrdr_T *Pnmrdr_T; 

struct Pnmrdr_T *Pnmrdr_new(FILE *); 
pixel Pnmrdr_get(Pnmrdr_T); 
void Pnmrdr_close(Pnmrdr_T); 
void Pnmrdr_free(Pnmrdr_T *rp); // frees memory and sets *rp = NULL 

प्रोग्रामिंग की यह शैली बहुत OO तरीकों के समान है।

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

मैं वास्तव में इस तरह से प्रोग्रामिंग, क्योंकि मैं सब कुछ है कि हो रहा है, देखने को मिलता है और अपने निजी डेटा संरचनाओं आँखों prying से सुरक्षित हैं :-)

+1

आईएमओ यह उत्तर स्वीकार किए गए व्यक्ति से काफी बेहतर है क्योंकि यह ग्लोबल्स का विकल्प देता है। चारों ओर डेटा पास करना लगभग हमेशा स्पष्ट होता है, भले ही यह पैरामीटर की संख्या को थोड़ा बढ़ाए। आपकी अंतर्दृष्टि के लिए धन्यवाद। –

0

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

  1. प्रत्येक वैश्विक चर को कक्षा का सदस्य बनाते हैं। तार्किक रूप से प्रत्येक वैश्विक चर आवेदन (या सिस्टम) से संबंधित है। बस एक आवेदन वर्ग बनाएँ। गुणों के रूप में वैश्विक वस्तुओं को परिभाषित करें। इसलिए जब उन्हें पहली बार बुलाया जाता है तो वे बनाए जाते हैं।

  2. एप्लिकेशन क्लास के लिए सिंगलटन बनाएं, ताकि आप इसे वैश्विक रूप से एक्सेस कर सकें।यह आपके कोड में एकमात्र सिंगलटन होगा। अच्छी तरह से, अंत में यह जावा में system.out या system.in ऑब्जेक्ट्स की तरह है।

नोट: मुझे पता है कि यह एक बहुत पुराना सवाल है, लेकिन अभी भी लोकप्रिय है।

+0

क्या आप विस्तार कर सकते हैं क्यों, अगर बिलकुल ऐसा सिंगलटन ग्लोबल्स से वास्तव में बेहतर है? सिंगलेट्स अक्सर (आमतौर पर?) इस तथ्य को कम करने के लिए केवल एक ठोस तरीका है कि आप वास्तव में वैश्विक स्थिति का उपयोग कर रहे हैं। मुझे लगता है कि आप यह कह रहे हैं कि कोई वस्तु में गेटर्स/सेटर्स के साथ चर को समाहित कर सकता है, लेकिन यह स्पष्ट नहीं है। यहां तक ​​कि उस मामले में, लोग तर्क देते हैं कि पैटर्न की मांग के सभी बॉयलरप्लेट के माध्यम से अपनी सिंगलटननेस को लागू करने की कोई वास्तविक आवश्यकता नहीं है; बस इसे एक से अधिक बार तुरंत न करें। –

संबंधित मुद्दे