2008-11-06 14 views
8

मैं निर्देशिका पेड़ों की तुलना करने के लिए कक्षा को कार्यान्वित कर रहा हूं (सी # में)। पहले मैंने कक्षा के निर्माता में वास्तविक तुलना लागू की। इस तरह:क्या इसे एक निर्माता में लंबे संचालन करने के लिए खराब डिजाइन माना जाता है?

DirectoryComparer c = new DirectoryComparer("C:\\Dir1", "C:\\Dir2"); 

लेकिन यह कन्स्ट्रक्टर में संभावित लंबा संचालन करने के लिए "सही" महसूस नहीं करता है। एक वैकल्पिक तरीका है कि कन्स्ट्रक्टर को निजी बनाना और इस तरह की स्थिर विधि जोड़ें:

DirectoryComparer c = DirectoryComparer.Compare("C:\\Dir1", "C:\\Dir2"); 

आपको क्या लगता है? क्या आप एक निर्माता को "त्वरित" होने की उम्मीद करते हैं? क्या दूसरा उदाहरण बेहतर है या क्या यह कक्षा के उपयोग को जटिल बना रहा है?

Btw:

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

संपादित करें:

बस मेरे उदाहरण एक छोटे से स्पष्ट करने के लिए। यदि निर्देशिका अलग-अलग होती है, तो मैं केवल तभी नहीं आती हूं, मुझे यह भी रूचि है कि वे कैसे भिन्न होते हैं (कौन सी फाइलें)। तो एक साधारण int वापसी मूल्य पर्याप्त नहीं होगा। Cdragon76.myopenid.com का उत्तर वास्तव में जो चाहता है उसके करीब है (आपको +1)।

+1

यदि आप कोई उत्तर नहीं चिह्नित करेंगे, तो शायद यह एक समुदाय विकी होना चाहिए? –

+0

मैं सहमत हूं [10chars] –

उत्तर

10

मैं दूसरा पसंद करता हूं।

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

3

आपको ऐसा कुछ भी नहीं करना चाहिए जो किसी निर्माता में विफल हो। आप कभी भी अमान्य वस्तुएं नहीं बनाना चाहते हैं। जबकि आप एक "ज़ोंबी" राज्य को कार्यान्वित कर सकते हैं जहां ऑब्जेक्ट ज्यादा नहीं करता है, अलग-अलग तरीकों से किसी जटिल तर्क को निष्पादित करना बेहतर होता है।

+0

एक निर्माता के असफल होने के लिए यह बिल्कुल ठीक है, और अपवाद फेंक दो। ढांचे में इसके कई उदाहरण हैं। यह सुनिश्चित करना चाहिए कि यह कन्स्ट्रक्टर के दौरान खुद के संदर्भ को रिसाव नहीं करता है, लेकिन इसके अलावा यह ठीक है। ऐसा नहीं है कि मुझे जटिल रचनाकार पसंद हैं, आपको दिमाग है। –

+0

मुझे नहीं लगता कि सिर्फ इसलिए कि यह ढांचे में है, यह ठीक है। ढांचा बहुत अच्छा है, लेकिन यह निर्दोष नहीं है। यह कहना बहुत अच्छी सलाह है कि आपको कभी ऐसी चीजें नहीं करनी चाहिए जो किसी निर्माता में विफल हो जाएं। लेकिन हां, अमान्य डेटा, आईएमएचओ के मामले में रचनाकारों को अपवाद फेंकने की अनुमति दी जानी चाहिए। – James

2

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

आप कन्स्ट्रक्टर को दो पथों को पारित करने की अनुमति देकर थोड़ा आसान बना सकते हैं, फिर एक तुलना() विधि है जो वास्तव में प्रसंस्करण करता है।

5

मुझे लगता है कि एक इंटरफ़ेस आपके बाद हो सकता है। मैं एक निर्देशिका का प्रतिनिधित्व करने के लिए एक वर्ग बनाउंगा, और यह DirectoryComparer इंटरफ़ेस को कार्यान्वित करेगा। उस इंटरफ़ेस में तुलना विधि शामिल होगी। यदि सी # में पहले से ही एक तुलनात्मक इंटरफ़ेस है, तो आप इसे भी कार्यान्वित कर सकते हैं।

कोड में, अपने कॉल होगा:

D1 = new Directory("C:\"); 
.. 
D1.compare(D2); 
1

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

12

मुझे लगता है कि दोनों का संयोजन "सही" विकल्प है, क्योंकि मैं तुलनात्मक तरीके से तुलना परिणाम की तुलना करने के लिए तुलना विधि की अपेक्षा करता हूं, तुलनात्मक रूप से नहीं।

DirectoryComparer c = new DirectoryComparer(); 

int equality = c.Compare("C:\\Dir1", "C:\\Dir2"); 

... और के रूप में दाना का उल्लेख है, वहाँ नेट में एक IComparer इंटरफ़ेस है कि इस पैटर्न को दर्शाता है।

IComparer.Compare विधि आईसीओएमपेयर कक्षाओं के उपयोग के बाद मुख्य रूप से सॉर्टिंग के साथ एक int लौटाती है।

  1. निर्माता (वैकल्पिक) पैरामीटर
  2. विधि दो "डाटा" पैरामीटर लेता है, उन्हें तुलना और एक "परिणाम देता है की तुलना करें" को विन्यस्त "के साथ एक उदाहरण initializes: सामान्य पैटर्न कि हालांकि में प्रश्न की समस्या से फिट बैठता है "

अब, परिणाम एक int, एक बूल, diffs का संग्रह हो सकता है। जो कुछ भी फिट बैठता है।

1

मैं एक सामान्य प्रयोजन comparer के लिए लगता है कि आप निर्माण पर केवल फ़ाइलें आप तुलना कर रहे हैं निर्दिष्ट और उसके बाद इस तरह बाद यह तुलना करने के लिए आप भी विस्तारित तर्क लागू कर सकते हैं कर सकते हैं:

  • तुलना करें फिर क्या हुआ अगर निर्देशिका बदल गई?
  • सदस्यों को अपडेट करके आप जिन फ़ाइलों की तुलना कर रहे हैं उन्हें बदलें।

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

बिंदु यह है कि आप यह मानकर सीमा लगा रहे हैं कि इस वर्ग का उपयोग केवल उन फ़ाइलों के एक उदाहरण के लिए तुलना करने के लिए किया जाएगा।

इसलिए, मैं पसंद करते हैं:

DirectoryComparer = new DirectoryComparer(&Dir1,&Dir2);

DirectoryComparer->Compare();

या

DirectoryComparer = new DirectoryComparer();

DirectoryComparer->Compare(&Dir1,&Dir2);

+0

मैं सहमत हूं, और आप अभी भी नई निर्देशिका कॉम्पैयर (ए, बी) कहकर एक लाइन कर सकते हैं। कॉम्पैयर() –

+0

@ डॉन: एक पूर्व सहकर्मी ने कहा कि "एक पंक्ति पर बहुत से सेक्सी चीजें करने की कोशिश कर रहा है"। यदि नया किसी भी कारण से विफल रहता है तो आपने अभी अपवाद का कारण बना दिया है जो ट्रैक करना मुश्किल हो सकता है। – tloach

0

आप के साथ सी # काम कर रहे हैं, तो आप विस्तार तरीकों का उपयोग कर सकता है 2 निर्देशिका की तुलना के लिए एक विधि बनाने के लिए है कि आप DirectoryClass में निर्माण से जुड़ा होगा, इसलिए यह कुछ चीज़ों को देखेंगे:

Directory dir1 = new Directory("C:\....."); 
Directory dir2 = new Directory("D:\....."); 

DirectoryCompare c = dir1.CompareTo(dir2); 

यह बहुत स्पष्ट कार्यान्वयन होगा। विस्तार विधियों पर अधिक here

0

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

3

मैं रचनाकारों के अंदर लंबे परिचालन नहीं करने की सामान्य भावना से सहमत हूं।

इसके अतिरिक्त, डिजाइन के विषय पर, मैं आपके दूसरे उदाहरण को बदलने पर विचार करता हूं ताकि DirectoryComparer.Compare विधि DirectoryComparer ऑब्जेक्ट के अलावा कुछ और लौटा दे। (शायद DirectoryDifferences या DirectoryComparisonResult नामक एक नई कक्षा।) DirectoryComparer प्रकार का एक ऑब्जेक्ट ऐसी ऑब्जेक्ट की तरह लगता है जिसका उपयोग आप निर्देशिका की तुलना करने के लिए निर्देशिकाओं की तुलना करने के लिए करेंगे जो निर्देशिकाओं की एक जोड़ी के बीच अंतर का प्रतिनिधित्व करता है।

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

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

DirectoryComparer comparer = new DirectoryComparer(
    DirectoryComparerOptions.IgnoreDirectoryAttributes 
); 
DirectoryComparerResult result = comparer.Compare("C:\\Dir1", "C:\\Dir2"); 
0

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

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

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

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

अवधारणात्मक रूप से एक कन्स्ट्रक्टर एक ऑब्जेक्ट का प्रतिनिधित्व करता है जो वस्तु का प्रतिनिधित्व करता है।

इंटीजर.वल्यूओएफ (1) के ऊपर परिभाषा द्वारा वास्तव में नए इंटीजर (1) की तुलना में एक कन्स्ट्रक्टर का अधिक है क्योंकि Integer.valueOf (1) == Integer.valueOf (1)। , किसी भी मामले में इस अवधारणा का भी अर्थ है कि सभी कॉन्सट्रक्टर तर्क, और केवल कन्स्ट्रक्टर तर्क, किसी ऑब्जेक्ट के बराबर व्यवहार को परिभाषित करना चाहिए।

0

मैं निश्चित रूप से दूसरा करूँगा।

एक कन्स्ट्रक्टर में लंबे कार्य ठीक हैं अगर वे वास्तव में ऑब्जेक्ट बना रहे हैं तो यह उपयोग योग्य है।

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

0

मुझे नहीं लगता कि "लम्बे" जैसे अमूर्त शब्दों के बारे में बात करने से निर्णय लेने के साथ कुछ भी करना पड़ता है यदि आप किसी कन्स्ट्रक्टर में कुछ डालते हैं या नहीं।

एक कन्स्ट्रक्टर ऐसा कुछ है जिसका उपयोग किसी ऑब्जेक्ट को प्रारंभ करने के लिए किया जाना चाहिए, "कुछ करने के लिए" विधि का उपयोग किया जाना चाहिए, यानी कोई फ़ंक्शन है।

1

मुझे लगता है कि एक कन्स्ट्रक्टर के लिए एक वैध वस्तु बनाने के लिए आवश्यक समय लेने के लिए केवल ठीक नहीं है, लेकिन कन्स्ट्रक्टर को ऐसा करने की आवश्यकता है। ऑब्जेक्ट सृजन करना बहुत खराब है क्योंकि आप संभावित रूप से अमान्य वस्तुओं के साथ समाप्त होते हैं। इसलिए, आपको इसे स्पर्श करने से पहले हर बार एक ऑब्जेक्ट की जांच करनी होगी (इस तरह यह एमएफसी में किया जाता है, आपके पास bool IsValid() हर जगह विधियां हैं)।

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

DirectoryComparer कक्षा क्या करती है? इसकी ज़िम्मेदारी क्या है? मेरे दृष्टिकोण से (जो एक सी ++ प्रोग्रामर का दृश्य है) ऐसा लगता है कि आप एक मुफ्त फ़ंक्शन का उपयोग करके बेहतर होंगे, लेकिन मुझे नहीं लगता कि आपके पास सी # में नि: शुल्क फ़ंक्शन हो सकते हैं, क्या आप? मुझे लगता है कि आप DirectoryComparer ऑब्जेक्ट में अलग-अलग फ़ाइलों को एकत्र करेंगे। यदि ऐसा है, तो आप बेहतर रूप से फाइलों या समकक्ष वर्ग की तरह कुछ बना सकते हैं जिसका नाम तदनुसार रखा गया है।

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

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