यह कम से कम कहने के लिए गूढ़ है क्योंकि आपने पहले से ही पहचान लिया है जो मुझे एक पल के लिए मेरे सिर को खरोंच कर सकता है जब मैं पहली बार आपके कोड का सामना करना शुरू कर देता हूं तो सोचें कि आप क्या कर रहे हैं और ये सहायक कक्षाएं तब तक लागू होती हैं जब तक मैं आपकी शैली को चुनना शुरू नहीं करता। / आदतें (जिस बिंदु पर मुझे इसकी पूरी तरह से आदत हो सकती है)।
मुझे यह पसंद है कि आप हेडर में जानकारी की मात्रा कम कर रहे हैं। विशेष रूप से बहुत बड़े कोडबेस में, जो संकलन-समय की निर्भरता को कम करने और अंततः समय का निर्माण करने के लिए व्यावहारिक प्रभाव डाल सकते हैं।
हालांकि मेरी प्रतिक्रिया यह है कि अगर आपको स्रोत फ़ाइल में आंतरिक लिंकेज के साथ मुक्त-कार्य करने के लिए पैरामीटर पारित करने के पक्ष में कार्यान्वयन के विवरण को छिपाने की आवश्यकता महसूस होती है। आमतौर पर आप उपयोगिता कार्यों (या पूरी कक्षाओं) को किसी विशेष वर्ग को लागू करने के लिए उपयोगी बना सकते हैं, ताकि वे क्लास के सभी इंटर्नल तक पहुंच प्राप्त कर सकें और इसके बजाय किसी विधि के कार्यान्वयन से लेकर फ़ंक्शन (या कंस्ट्रक्टर) तक संबंधित लोगों को पास कर सकें। और स्वाभाविक रूप से आपके वर्ग और "सहायकों" के बीच युग्मन को कम करने का बोनस है। इसमें यह भी सामान्य करने की प्रवृत्ति है कि क्या हो सकता है अन्यथा "हेल्पर्स" आगे भी हो यदि आप पाते हैं कि वे एक से अधिक वर्ग कार्यान्वयन के लिए लागू सामान्यीकृत उद्देश्य की सेवा शुरू कर रहे हैं।
जब कभी-कभी मुझे कोड में बहुत सारे "हेल्पर्स" दिखाई देते हैं, तो मैं कभी-कभी थोड़ा सा ऐंठता हूं। यह हमेशा सच नहीं होता है, लेकिन कभी-कभी वे एक डेवलपर के लक्षण हो सकते हैं, जो कोड डुप्लीकेशन को खत्म करने के लिए सिर्फ विली-निली का काम कर रहे हैं, डेटा के विशाल ब्लूब के साथ कोड को समाप्त करने के लिए बमुश्किल बोधगम्य नामों / उद्देश्यों के साथ कार्यों के लिए पारित किया जा रहा है, इस तथ्य से परे कि वे किस राशि को कम करते हैं कुछ अन्य कार्यों को लागू करने के लिए आवश्यक कोड। बस थोड़ा सा नन्हा सा अधिक सोचा हुआ अपफ्रंट कभी-कभी एक वर्ग के कार्यान्वयन को आगे के कार्यों में विघटित होने के संदर्भ में बहुत अधिक स्पष्टता का कारण बन सकता है, और विशिष्ट मापदंडों को पूरा करने के पक्ष में आंतरिक तक पूरी पहुंच के साथ अपनी वस्तु के पूरे उदाहरणों को पारित करने में मदद कर सकता है। सोचा था कि डिजाइन की शैली को बढ़ावा देने के। मेरा सुझाव है कि आप ऐसा कर रहे हैं, निश्चित रूप से (मुझे पता नहीं है),
अगर यह बेकार हो जाता है, तो मैं एक दूसरा, अधिक मुहावरेदार समाधान पर विचार करूंगा जो कि पिम्पल है (मुझे एहसास है कि आपने इसके साथ मुद्दों का उल्लेख किया है लेकिन मुझे लगता है कि आप न्यूनतम प्रयास से बचने के लिए एक समाधान को सामान्य कर सकते हैं)। यह पूरी जानकारी को स्थानांतरित कर सकता है कि हेडर थोक से दूर अपने निजी डेटा सहित आपकी कक्षा को लागू करने की आवश्यकता है। पिंपल के प्रदर्शन के मुद्दों को काफी हद तक एक गंदगी-सस्ते निरंतर-समय के आवंटन के साथ कम किया जा सकता है * एक पूर्ण सूची की तरह, पूर्ण-उपयोगकर्ता-परिभाषित प्रतिलिपि ctor को लागू किए बिना मूल्य शब्दार्थ को संरक्षित करते हुए।
- प्रदर्शन पहलू के लिए पिंपल बहुत कम से कम एक पॉइंटर ओवरहेड को पेश करता है, लेकिन मुझे लगता है कि मामलों को काफी गंभीर होना चाहिए जहां एक व्यावहारिक चिंता है। यदि स्थानिक स्थानीयता को आवंटनकर्ता के माध्यम से महत्वपूर्ण रूप से कम नहीं किया जाता है, तो आपका तंग वस्तु पर घूमता है (जो आम तौर पर सजातीय होना चाहिए यदि प्रदर्शन इतना ही है कि चिंता का विषय है) अभी भी व्यवहार में कैश मिसेज को कम करने के लिए आप कुछ का उपयोग करते हैं पिंपल को आवंटित करने के लिए एक स्वतंत्र सूची, वर्ग के क्षेत्रों को बड़े पैमाने पर सन्निहित स्मृति ब्लॉकों में डालती है।
व्यक्तिगत रूप से उन संभावनाओं को समाप्त करने के बाद ही मैं कुछ इस तरह से विचार करूंगा। मुझे लगता है कि यह एक अच्छा विचार है अगर विकल्प हेडर के संपर्क में अधिक निजी तरीकों की तरह है, जिसके साथ शायद यह केवल गूढ़ प्रकृति का व्यावहारिक चिंता है।
एक विकल्प
एक विकल्प जो मेरे सिर में अभी-अभी आया है जो आपके समान उद्देश्यों को पूरा करता है अनुपस्थित मित्र इस तरह हैं:
struct PredicateListData
{
int somePrivateField;
};
class PredicateList
{
PredicateListData data;
public:
bool match() const;
};
// In source file:
static bool fullMatch(const PredicateListData& p)
{
// Can access p.somePrivateField here.
}
bool PredicateList::match() const
{
return fullMatch(data);
}
अब यह एक बहुत अंतर अंतर की तरह लग सकता है और मैं इसे अभी भी "सहायक" कहूंगा (संभवतः एक अपमानजनक अर्थ में क्योंकि हम अभी भी कक्षा के पूरे आंतरिक राज्य को फ़ंक्शन में पास कर रहे हैं, चाहे उसे यह सब चाहिए या नहीं) सिवाय इसके कि मुठभेड़ के "सदमे" कारक से बचें friend
। सामान्य रूप friend
से अक्सर अनुपस्थित निरीक्षण को देखने के लिए थोड़ा डरावना लगता है, क्योंकि यह कहता है कि आपका वर्ग इंटर्न कहीं और पहुंच सकता है (जो इस निहितार्थ को वहन करता है कि यह अपने स्वयं के आक्रमणकारियों को बनाए रखने में असमर्थ हो सकता है)। जिस तरह से आप friend
इसका इस्तेमाल कर रहे हैं, अगर लोग अभ्यास के बारे में जानते हैं तो यह बहुत ही कम हो जाता हैfriend
बस उसी स्रोत फ़ाइल में रहता है जो कक्षा की निजी कार्यक्षमता को लागू करने में मदद करता है, लेकिन उपरोक्त कम से कम एक संभावित लाभ के साथ एक ही प्रभाव को पूरा करता है कि यह किसी भी मित्र को शामिल नहीं करता है जो उस तरह से बचता है ("ओह!" शूट करें, इस क्लास में एक दोस्त है। इसके निजी हिस्से को कहां से एक्सेस / म्यूट किया गया है? ")। जबकि ऊपर दिए गए संस्करण के तुरंत बाद यह सूचित करता है कि निजीकरण के लिए कोई तरीका नहीं है जिसके कार्यान्वयन में किए गए किसी भी चीज के बाहर पहुँचा / म्यूट किया गया हो PredicateList
।
यह शायद कुछ हद तक इस तरह की अति सूक्ष्म अंतर वाले क्षेत्रों की ओर बढ़ रहा है क्योंकि कोई भी जल्दी से यह पता लगा सकता है कि क्या आप चीजों को समान रूप से नाम देते हैं *Helper*
और उन सभी को एक ही स्रोत फ़ाइल में डालते हैं जो कि एक वर्ग के निजी कार्यान्वयन के हिस्से के रूप में एक साथ बंडल किया गया है। लेकिन अगर हमें नाइट-पिकी मिलता है, तो हो सकता है कि तुरंत ऊपर की शैली एक नज़र में घुटने-झटका की प्रतिक्रिया के रूप में पैदा नहीं करेगी, friend
जो कीवर्ड को अनुपस्थित करता है जो थोड़ा डरावना लगता है।
अन्य प्रश्नों के लिए:
एक उपभोक्ता अपने स्वयं के वर्ग PredicateList_HelperFunctions को परिभाषित कर सकता है, और उन्हें निजी क्षेत्रों तक पहुंचने दे सकता है। हालांकि मैं इसे एक बड़े मुद्दे के रूप में नहीं देखता (यदि आप वास्तव में उन निजी क्षेत्रों में चाहते थे जो आप कुछ कास्टिंग कर सकते थे), तो शायद यह उपभोक्ताओं को इस तरह से उपयोग करने के लिए प्रोत्साहित करेगा।
यह एपीआई सीमाओं के पार एक संभावना हो सकती है जहां क्लाइंट एक ही नाम के साथ दूसरी श्रेणी को परिभाषित कर सकता है और लिंकेज त्रुटियों के बिना इस तरह से आंतरिक तक पहुंच प्राप्त कर सकता है। फिर से मैं काफी हद तक ग्राफिक्स में काम करने वाला एक सी कोडर हूं, जहां प्राथमिकता सूची में "क्या अगर" के स्तर पर सुरक्षा चिंताएं बहुत कम हैं, इसलिए इन जैसी चिंताएं सिर्फ मैं हूं जो मैं अपने हाथों को लहराने और नृत्य करने के लिए हूं। बहाना बनाने की कोशिश करो जैसे वे मौजूद नहीं हैं। :-D यदि आप एक ऐसे डोमेन में काम कर रहे हैं जहाँ इन जैसी चिंताएँ गंभीर हैं, हालाँकि मुझे लगता है कि इसे बनाने के लिए एक अच्छा विचार है।
उपरोक्त वैकल्पिक प्रस्ताव भी इस मुद्दे को भुगतने से बचता है। यदि आप अभी भी उपयोग करने के लिए छड़ी करना चाहते हैं friend
, तो आप सहायक को एक निजी नेस्टेड वर्ग बनाकर उस मुद्दे से भी बच सकते हैं।
class PredicateList
{
...
// Declare nested class.
class Helper;
// Make it a friend.
friend class Helper;
public:
...
};
// In source file:
class PredicateList::Helper
{
...
};
क्या यह एक प्रसिद्ध डिज़ाइन पैटर्न है जिसका कोई नाम है?
मेरी जानकारी के लिए कोई नहीं। मुझे संदेह है कि कार्यान्वयन के विवरण और शैली के वास्तव में होने के बाद से कोई एक होगा।
"हेल्पर हेल"
मुझे इस बात पर आगे स्पष्टीकरण के लिए अनुरोध मिला कि कैसे मैं कभी-कभी उखड़ जाता हूं जब मैं "हेल्पर" कोड के बहुत से कार्यान्वयन देखता हूं, और यह कुछ के साथ थोड़ा विवादास्पद हो सकता है, लेकिन यह वास्तव में तथ्यात्मक है क्योंकि मैंने वास्तव में जब मैं बहस कर रहा था तब मैं बहुत ही खराब हो गया था मेरे सहकर्मियों के "सहायकों" का भार खोजने के लिए केवल एक वर्ग का कार्यान्वयन। :-D और मैं केवल अपने सिर को खरोंचने वाली टीम पर यह पता लगाने की कोशिश नहीं कर रहा था कि इन सभी सहायकों को वास्तव में क्या करना है। मैं यह भी कहना चाहता हूं कि "आप मदद करने वालों का उपयोग नहीं करेंगे" जैसे हठधर्मिता से बाहर आना चाहते हैं , लेकिन मैं एक छोटा सुझाव दूंगा कि यह सोचने में मदद मिल सकती है कि व्यावहारिक होने पर उनमें से अनुपस्थित चीजों को कैसे लागू किया जाए।
क्या सभी निजी सदस्य कार्य परिभाषा के अनुसार सहायक कार्य नहीं कर रहे हैं?
और हां, मैं निजी तरीकों में शामिल हूं। अगर मैं एक सीधा सार्वजनिक इंटरफ़ेस की तरह साथ लेकिन निजी तरीकों की एक अंतहीन सेट जो कुछ हद तक की तरह उद्देश्य में ख़राब ढंग से परिभाषित कर रहे हैं की तरह एक वर्ग को देखने find_impl
या find_detail
या find_helper
है, तो मैं भी एक समान तरीके से चापलूसी।
मैं एक विकल्प के रूप में जो सुझाव दे रहा हूं, वह static
आपके वर्ग को "एक फ़ंक्शन जो दूसरों को लागू करने में मदद करता है" की तुलना में कम से अधिक सामान्यीकृत उद्देश्य के साथ अपने वर्ग को लागू करने में मदद करने के लिए आंतरिक लिंकेज (घोषित या अनाम नामस्थान के साथ) का उपयोग नहीं करता है। और मैं सी + + 'कोडिंग मानकों' से हर्ब सटर का हवाला दे सकता हूं कि यहां सामान्य एसई दृष्टिकोण से बेहतर क्यों हो सकता है:
सदस्यता शुल्क से बचें: जहाँ संभव हो, फ़ंक्शंस को गैर-मित्रवत मित्र बनाना पसंद करें। [...] गैर-मित्रवत गैर-कानूनी कार्य निर्भरता को कम करके एनकैप्सुलेशन में सुधार करते हैं: फ़ंक्शन का शरीर कक्षा के गैर-गणमान्य सदस्यों पर निर्भर होने के लिए नहीं आ सकता है (देखें आइटम ११)। वे अलग करने योग्य कार्यक्षमता को मुक्त करने के लिए अखंड वर्गों को तोड़ते हैं, आगे युग्मन को कम करते हैं (देखें आइटम 33)।
आप "सदस्यता शुल्क" को भी समझ सकते हैं कि वह चर दायरे को कम करने के बुनियादी सिद्धांत के संदर्भ में कुछ हद तक बात करता है। यदि आप सबसे चरम उदाहरण के रूप में कल्पना करते हैं, तो एक ईश्वर वस्तु जिसे चलाने के लिए आपके पूरे कार्यक्रम के लिए आवश्यक सभी कोड हैं, तो इस प्रकार के "सहायकों" का पक्ष लेते हैं (कार्य, चाहे सदस्य कार्य या मित्र) जो सभी इंटर्नल का उपयोग कर सकते हैं ( एक वर्ग के निजी) मूल रूप से उन चरों को प्रस्तुत करते हैं जो वैश्विक चरों की तुलना में कम समस्याग्रस्त नहीं हैं। आपके पास राज्य को सही ढंग से प्रबंधित करने और सुरक्षा सुनिश्चित करने और आक्रमणकारियों को बनाए रखने की सभी कठिनाइयां हैं जो आपको इस सबसे चरम उदाहरण में वैश्विक चर के साथ मिलेंगी। और निश्चित रूप से अधिकांश वास्तविक उदाहरण उम्मीद से कहीं भी इस चरम के करीब नहीं हैं, लेकिन जानकारी छिपाना केवल उतना ही उपयोगी है क्योंकि यह जानकारी के दायरे को सीमित कर रहा है।
अब सटर पहले से ही यहां एक अच्छी व्याख्या देता है, लेकिन मैं आगे यह भी जोड़ूंगा कि डिकॉउपलिंग एक मनोवैज्ञानिक सुधार (कम से कम अगर आपका दिमाग मेरी तरह काम करता है) को बढ़ावा देता है तो आप कैसे कार्य करते हैं। जब आप ऐसे फ़ंक्शन डिज़ाइन करना शुरू करते हैं जो कक्षा में सब कुछ एक्सेस नहीं कर सकते हैं केवल आपके द्वारा इसे पारित करने वाले प्रासंगिक मापदंडों को छोड़कर या, यदि आप कक्षा के उदाहरण को एक पैरामीटर के रूप में पास करते हैं, तो केवल इसके सार्वजनिक सदस्य, यह एक डिजाइन मानसिकता को बढ़ावा देने के लिए जाता है जो एहसान करता है जिन कार्यों का स्पष्ट उद्देश्य होता है, डिकॉप्लिंग के शीर्ष पर और बेहतर इनकैप्सुलेशन को बढ़ावा देने की तुलना में, यदि आप अन्यथा सब कुछ एक्सेस कर सकते हैं तो आपको डिजाइन करने के लिए लुभाया जा सकता है।
यदि हम चरम सीमाओं पर वापस जाते हैं तो वैश्विक चर के साथ कोडबेड कोडबेड डेवलपर्स को कार्यों को डिजाइन करने के लिए बिल्कुल पसंद नहीं करता है जो स्पष्ट रूप से और उद्देश्य में सामान्यीकृत है। बहुत जल्दी आप एक समारोह में अधिक जानकारी प्राप्त कर सकते हैं, हम में से कई लोग नश्वरता का सामना करने के लिए इसे अध: पतन करने के लिए प्रलोभन का सामना करते हैं और इस सभी अतिरिक्त जानकारी तक पहुँचने के पक्ष में अपनी स्पष्टता को कम कर देते हैं जो हमारे पास उस फ़ंक्शन के लिए अधिक विशिष्ट और प्रासंगिक मापदंडों को स्वीकार करने के बजाय है। राज्य तक अपनी पहुंच को कम करने और अपनी प्रयोज्यता को व्यापक बनाने और इरादों की अपनी स्पष्टता में सुधार करने के लिए। यह लागू होता है (हालांकि आम तौर पर कुछ हद तक कम) सदस्य कार्यों या दोस्तों के साथ।