सी में "विनाशकारी" को छोड़ना YAGNI को बहुत दूर ले जा रहा है?


9

मैं O- जैसी तकनीकों का उपयोग करके C में एक मध्यम एम्बेडेड एप्लिकेशन पर काम कर रहा हूं। मेरी "कक्षाएं" डेटा स्ट्रक्चर्स और फ़ंक्शन पॉइंटर्स स्ट्रक्चर्स का उपयोग करते हुए एन्कैप्सुलेशन, बहुरूपता और निर्भरता इंजेक्शन का उपयोग करने के लिए .h / .c मॉड्यूल हैं।

अब, कोई myModule_create(void)एक myModule_destroy(pointer)प्रतिपक्ष के साथ आने की अपेक्षा करेगा । लेकिन परियोजना अंतःस्थापित की जा रही है, जो संसाधन वास्तविक रूप से त्वरित हैं, उन्हें कभी जारी नहीं किया जाना चाहिए।

मेरा मतलब है, अगर मेरे पास 4 UART सीरियल पोर्ट हैं और मैं उनके आवश्यक पिन और सेटिंग्स के साथ 4 UART इंस्टेंस बनाते हैं, तो रनटाइम के दौरान कभी भी UART # 2 को नष्ट करने का कोई कारण नहीं है।

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


4
यदि आप ऑब्जेक्ट को डिस्पोज़ करने का कोई तरीका प्रदान नहीं करते हैं, तो आप एक स्पष्ट संदेश दे रहे हैं कि उनके पास एक बार बनाया गया "अनंत" जीवनकाल है। यदि यह आपके आवेदन के लिए समझ में आता है, तो मैं कहता हूं: यह करो।
Glampert

4
यदि आप अपने विशेष उपयोग के मामले में उस प्रकार को युग्मित करने के लिए जा रहे हैं, तो एक myModule_create(void)फ़ंक्शन भी क्यों है? आप केवल उस विशिष्ट उदाहरण को हार्ड-कोड कर सकते हैं जिसे आप अपने द्वारा बताए गए इंटरफ़ेस में उपयोग करने की अपेक्षा करते हैं।
डोभाल

@ डोवल मैंने इसके बारे में सोचा। मैं अपने पर्यवेक्षक से कोड के कुछ हिस्सों और बिट्स का उपयोग करके इंटर्न हूं, इसलिए मैं अनुभव के लिए C में OO शैली का प्रयोग करके "कंपनी सही तरीके से कर रहा हूं" और कंपनी के मानकों के साथ स्थिरता के साथ काम करने की कोशिश कर रहा हूं।
Asics

2
@glampert इसे नाखून; मुझे लगता है कि आप बनाने के कार्य के प्रलेखन में अपेक्षित-अनंत जीवनकाल को साफ करना चाहिए।
ब्लरफुल

जवाबों:


11

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

Glampert सही है; यहां विध्वंसक की कोई जरूरत नहीं है। वे केवल उपयोगकर्ताओं के लिए कोड ब्लोट और एक गड्ढा बनाएंगे (एक ऑब्जेक्ट का उपयोग करके इसके विनाशकर्ता को अपरिभाषित व्यवहार कहा जाता है)।

हालांकि, आपको यह सुनिश्चित करना चाहिए कि वस्तुओं को निपटाने की वास्तव में आवश्यकता नहीं है। उदाहरण के लिए, क्या आपको एक UART के लिए एक ऑब्जेक्ट की आवश्यकता है जो वर्तमान में उपयोग में नहीं है?


3

मेमोरी लीक का पता लगाने का सबसे आसान तरीका यह है कि आप अपने आवेदन को सफाई से बाहर कर सकें। कई कंपाइलर / वातावरण स्मृति के लिए जाँच करने का एक तरीका प्रदान करते हैं जो आपके आवेदन से बाहर निकलने पर अभी भी आवंटित किया जाता है। यदि कोई प्रदान नहीं किया गया है तो आमतौर पर बाहर निकलने से पहले कुछ कोड जोड़ने का एक तरीका है जो इसे समझ सकता है।

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


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

@ कोड: अपने आप को सीमित करने का कोई कारण नहीं है। यद्यपि आप उस महान डिज़ाइन के साथ आ सकते हैं जो स्टार्टअप पर मेमोरी को पूर्व-आबंटित करता है, जब आपके साथ आने वाले लोग इस भव्य योजना के लिए निजी नहीं होते हैं या इसके महत्व को देखने में विफल रहते हैं, तो वे मेमोरी को आवंटित करेंगे उड़ना और वहाँ अपने डिजाइन चला जाता है। बस इसे सही करें और आवंटित / डी-आवंटित करें और सत्यापित करें कि आपने वास्तव में क्या काम किया है। यदि आपके पास वास्तव में एक स्मृति बाधित डिवाइस है, तो आमतौर पर जो किया जाता है वह नए ऑपरेटर / मॉलोक को ओवरराइड करने और आवंटन ब्लॉकों को फिर से व्यवस्थित करने के लिए है।
डंक

3

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

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

इसलिए, मेरे अनुभव में, YAGNI में "aint't" एक "are" से निकला है और मैंने हर वर्ग के लिए विध्वंसक बनाना समाप्त कर दिया है कि मुझे लगा कि मुझे इसकी आवश्यकता है या नहीं। यहां तक ​​कि अगर मैंने परीक्षण को छोड़ दिया है, तो कम से कम एक सही ढंग से डिज़ाइन किया गया विध्वंसक खराब स्लब के लिए मौजूद है जो मेरे बाद एक होगा। (और, बहुत कम मूल्य के लिए, यह कोड को इस मामले में अधिक पुन: प्रयोज्य बनाता है कि इसका उपयोग उस वातावरण में किया जा सकता है जहां इसे नष्ट कर दिया जाएगा।)

जबकि वह YAGNI को संबोधित करता है, यह मृत कोड को संबोधित नहीं करता है। उसके लिए, मुझे लगता है कि एक सशर्त संकलन मैक्रो कुछ #define BUILD_FOR_TESTING की तरह अंतिम उत्पादन बिल्ड से विध्वंसक को समाप्त करने की अनुमति देता है।

इसे इस तरह से करना: आपके पास परीक्षण / भविष्य के पुन: उपयोग के लिए विध्वंसक है, और आप YAGNI और "कोई मृत कोड" नियमों के डिजाइन उद्देश्यों को पूरा नहीं करते हैं।


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

0

आपके पास एक नो-ऑप डिस्ट्रक्टर हो सकता है, जैसे कुछ

  void noop_destructor(void*) {};

तब Uartशायद उपयोग करने का विनाशकर्ता सेट करें

  #define Uart_destructor noop_destructor

(यदि आवश्यक हो तो उपयुक्त कलाकारों को जोड़ें)

दस्तावेज़ के लिए मत भूलना। शायद आप भी चाहते हैं

 #define Uart_destructor abort

वैकल्पिक रूप से, कॉमन कोड को नष्ट करने वाले कॉमन कोड में विशेष केस तब होता है जब डिस्ट्रक्टर पॉइंटर फ़ंक्शन NULLइसे कॉल करने से बचने के लिए होता है।

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