आपको स्थिरांक कहां और क्यों रखना चाहिए?


34

हमारे ज्यादातर बड़े अनुप्रयोगों में, हमारे पास आमतौर पर "स्थिरांक" के लिए कुछ ही स्थान होते हैं:

  • GUI और आंतरिक प्रतियोगियों के लिए एक वर्ग (टैब पृष्ठ शीर्षक, समूह बॉक्स शीर्षक, गणना कारक, गणना)
  • डेटाबेस तालिकाओं और स्तंभों के लिए एक वर्ग (यह भाग उत्पन्न कोड है) प्लस उनके लिए पठनीय नाम (मैन्युअल रूप से सौंपा गया)
  • आवेदन संदेशों के लिए एक वर्ग (लॉगिंग, संदेश बॉक्स आदि)

स्थिरांक को आमतौर पर उन वर्गों में अलग-अलग संरचनाओं में विभाजित किया जाता है। हमारे C ++ अनुप्रयोगों में, स्थिरांक केवल .h फ़ाइल में परिभाषित किए जाते हैं और मान .cpp फ़ाइल में दिए जाते हैं।

एक लाभ यह है कि सभी तार आदि एक केंद्रीय स्थान पर हैं और हर कोई जानता है कि उन्हें कहां खोजना है जब कुछ बदलना होगा।

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

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

हालाँकि, मुझे कुछ नुकसान दिखाई देते हैं:

  • हर एक वर्ग को स्थिरांक वर्गों से कसकर जोड़ा जाता है
  • जोड़ने / हटाने / नाम बदलने / एक स्थिरांक को स्थानांतरित करने के लिए कम से कम 90% अनुप्रयोग की पुन: प्राप्ति की आवश्यकता होती है (नोट: मूल्य बदलना, कम से कम C ++ के लिए)। 1500 सी के साथ हमारी सी ++ परियोजनाओं में से, इसका मतलब है कि लगभग 7 मिनट का संकलन समय (प्री-कंपाइल किए गए हेडफ़ोन का उपयोग करना, उनके बिना यह लगभग 50 मिनट है) प्लस कुछ स्थिर पुस्तकालयों के खिलाफ लिंक करने के 10 मिनट के आसपास।
  • विजुअल स्टूडियो कम्पाइलर के माध्यम से एक गति अनुकूलित रिलीज का निर्माण करने में 3 घंटे तक का समय लगता है। मुझे नहीं पता कि वर्ग संबंधों की विशाल राशि स्रोत है या हो सकती है।
  • आप अस्थायी रूप से हार्ड-कोडिंग स्ट्रिंग्स को कोड में सीधे संचालित करते हैं क्योंकि आप बहुत जल्दी कुछ परीक्षण करना चाहते हैं और उस परीक्षण के लिए केवल 15 मिनट इंतजार नहीं करना चाहते हैं (और शायद हर बाद एक)। हर कोई जानता है कि "मैं बाद में ठीक कर दूंगा" - क्या होता है।
  • किसी अन्य परियोजना में एक कक्षा का पुन: उपयोग करना हमेशा इतना आसान नहीं होता है (मुख्यतः अन्य तंग युग्मन के कारण, लेकिन स्थिरांक संभालना इतना आसान नहीं होता है।)

आप इस तरह से स्थिरांक कहाँ संग्रहीत करेंगे? इसके अलावा आप अपने प्रोजेक्ट मैनेजर को यह समझाने के लिए क्या तर्क लाएंगे कि बेहतर अवधारणाएँ हैं जो ऊपर सूचीबद्ध लाभों का अनुपालन करती हैं?

सी ++ - विशिष्ट या स्वतंत्र उत्तर देने के लिए स्वतंत्र महसूस करें।

पुनश्च: मुझे पता है कि यह प्रश्न व्यक्तिपरक है, लेकिन मैं ईमानदारी से इस तरह के प्रश्न के लिए इस साइट से बेहतर कोई स्थान नहीं जानता।

इस प्रोजेक्ट पर अपडेट करें

मेरे पास संकलन समय पर समाचार है:
कालेब और gbjbaanb के पोस्ट के बाद, मैंने अपने कॉन्स्टेंट फ़ाइल को कई अन्य फाइलों में विभाजित किया जब मेरे पास समय था। मैंने अंततः अपनी परियोजना को कई पुस्तकालयों में विभाजित किया जो अब बहुत आसान था। इसे रिलीज़ मोड में संकलित करने से पता चला कि ऑटो-जनरेटेड फ़ाइल में डेटाबेस परिभाषाएँ (तालिका, स्तंभ नाम और अधिक - 8000 से अधिक प्रतीक हैं) और कुछ हैश के निर्माण में रिलीज़ मोड में विशाल संकलन समय होता है।

लाइब्रेरी के लिए MSVC के ऑप्टिमाइज़र को निष्क्रिय करना जिसमें DB कॉन्स्टेंट शामिल हैं, अब हमें आपके प्रोजेक्ट के कुल संकलन समय (कई एप्लिकेशन) को रिलीज़ मोड में 8 घंटे से लेकर एक घंटे से कम करने की अनुमति देता है!

हमें अभी तक यह पता नहीं चल पाया है कि एमएसवीसी के पास इन फाइलों का अनुकूलन करने में इतना कठिन समय क्यों है, लेकिन अब इस बदलाव से बहुत अधिक दबाव में राहत मिलती है क्योंकि अब हमें केवल रात के निर्माण पर निर्भर रहना होगा।

यह तथ्य - और अन्य लाभ, जैसे कम तंग युग्मन, बेहतर पुन: प्रयोज्य आदि - यह भी दिखाया कि "स्थिरांक" को विभाजित करने में समय बिताना इतना बुरा विचार नहीं था; ;-)

Update2

चूँकि यह प्रश्न अभी भी कुछ ध्यान देता है:
यहाँ मैं पिछले कुछ वर्षों में कर रहा हूँ:

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

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

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

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


2
व्यक्तिगत रूप से मेरे पास निरंतर रूप से UI शीर्षक या संदेश तार नहीं होंगे। मैं उन्हें app.config
jk में था।

1
मुझे यह पसंद है कि आप इसे अभी कैसे कर रहे हैं - मैं आपके नुकसान को समझता हूं लेकिन हमें इससे निपटना होगा।
Bigtang

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

तंग युग्मन एक समस्या नहीं है, क्योंकि यही आप वास्तव में चाहते हैं। आप चाहते हैं कि आपकी स्थिरांक फ़ाइल में एक परिवर्तन संभवत: बहुत सारी स्रोत फ़ाइलों को प्रभावित करे। (बेशक आपको अन्य समस्याएं भी हैं)।
gnasher729

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

जवाबों:


29

एक वर्ग के लिए विशिष्ट हैं जो उस वर्ग के इंटरफ़ेस में जाना चाहिए।

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

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


1
मामले में आप रुचि रखते हैं: मैंने आपके प्रश्न का अद्यतन किया है जो मैंने प्राप्त किया है, आपके उत्तर और अन्य के बाद
टिम मेयर

6

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

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


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

मामले में आप रुचि रखते हैं: मैंने आपके प्रश्न का अद्यतन किया है जो मैंने प्राप्त किया है, आपके उत्तर और अन्य के बाद
टिम मेयर

2

नोट: मैं C ++ डेवलपर नहीं हूं ... लेकिन यहां मेरा विचार है: आपको कॉन्फ़िगरेशन फ़ाइलों के बीच अंतर के बारे में @ jk की टिप्पणी पर विचार करने की आवश्यकता है। डॉटनेट में, ऐसी संसाधन फ़ाइल होती हैं जिनका उपयोग ऐसी सूचनाओं को संग्रहीत करने के लिए किया जाता है। Windows प्रपत्र में, प्रत्येक प्रपत्र के लिए VS से एक संसाधन फ़ाइल बनाए रखी जाती है।

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

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

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


2

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

जितना अधिक वे अपने दायरे के लिए परिभाषित होते हैं उतना ही उच्च प्रदर्शन होता है।

जितना अधिक वे तार्किक रूप से और अपने दायरे के बाहर समूहीकृत होते हैं, पुन: प्रयोज्यता उतनी ही अधिक होती है।

लागत जितनी कम सुलभ होती है, सुरक्षा उतनी ही अधिक होती है।

एक निरंतर जीवनकाल जितना अधिक होता है, उतनी ही कम परवाह करता है कि आपने इसे कहां रखा है।

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

कम स्थिरांक में एक स्थिर लेकिन एक चर (जैसे संस्करण संख्या) का चरित्र होता है जितना अधिक आप इसे बाहर रख सकते हैं। कम चर स्थिर है, इसलिए यह जितना अधिक स्थिर है, उतना ही इसके दायरे में रखा जाना चाहिए। डिबगिंग के दौरान संकलन समय को कम करने के लिए इसे बाहर रखने के लिए समझ में आता है।

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


1

मैं इन सभी स्थिरांक को किसी प्रकार की विन्यास फाइल में डालने का सुझाव दूंगा। जावा अनुप्रयोगों के लिए, हम आमतौर पर .properties फ़ाइलों का उपयोग करते हैं, प्रत्येक पंक्ति के साथ एक सरल पाठ "(कुंजी) = (मान)" के रूप में स्वरूपित होता है। उदाहरण

MainPanel.Title = हमारे आवेदन में आपका स्वागत है
DB.table.users = TBL_USERS
logging.filename = application.log

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

एक कार्यान्वयन के लिए, मुझे यह SO प्रश्न मिला: https://stackoverflow.com/questions/874052/properties-file-library-for-c-or-c (यह Google खोज पर पहली हिट थी - मैंने नहीं वास्तव में खुद इस सॉफ्टवेयर का इस्तेमाल किया)।


C ++ प्रोजेक्ट्स के लिए, यदि हम कोई मान बदलते हैं, तो हमें केवल स्थिरांक फ़ाइल को फिर से जमा करना होगा। ऐसा इसलिए है क्योंकि मान को एक .cpp फ़ाइल में असाइन किया गया है। हालाँकि जोड़ना / हटाना / नाम बदलना / स्थिर रहना अभी भी एक पूर्ण पुनर्निर्माण की आवश्यकता है
टिम मेयर

@TimMeyer: यदि आप स्थिरांक को कई फ़ाइलों में विभाजित करते हैं, तो एक स्थिरांक को जोड़ने / हटाने से केवल उन फ़ाइलों को प्रभावित होगा जो उस विशेष फ़ाइल पर निर्भर हैं, सही?
FrustratedWithFormsDesigner

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

हालाँकि, मैंने वास्तव में कई स्थिरांक फ़ाइलों को एक ही स्थान पर रखने के बारे में नहीं सोचा है
टिम मेयर

+1। @ समय मेयर: इस उद्देश्य के लिए, संकलन-समय की जाँच करने से लागत अधिक बचती है। इसके अलावा, यदि आप को अंतर्राष्ट्रीयकरण करने की आवश्यकता है तो आप क्या करने जा रहे हैं?
केविन क्लाइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.