5

पर इंगित करेंगे, मेरे वर्तमान प्रोजेक्ट पर हमने कोड मेट्रिक्स "रखरखाव सूचकांक" और "साइक्लोमेटिक कॉम्प्लेक्सिटी" कोड के लिए कुछ लक्ष्य निर्धारित किए हैं। रखरखाव सूचकांक 60 या उच्चतम और साइक्लोमेटिक जटिलता 25 या उससे कम होना चाहिए। हम जानते हैं कि 60 और उच्चतम के रखरखाव सूचकांक एक बहुत अधिक है।क्या आप अपने LINQ प्रश्नों को एक्सटेंशन विधियों में

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

उदाहरण के लिए LINQ क्वेरी बनाम विस्तार विधि निम्नलिखित:

LINQ क्वेरी

List.Where(m => m.BeginTime >= selectionFrom && m.EndTime <= selectionTo) 

एक्सटेंशन विधि:

public static IEnumerable<MyType> FilterBy(this IEnumerable<MyType> source, DateTime selectionFrom, DateTime selectionTo) 
{ 
    return (IEnumerable<MyType>)source.Where(m => m.BeginTime >= selectionFrom && m.EndTime <= selectionTo); 
} 

List.FilterBy(selectionFrom, selectionTo); 

विस्तार विधि मुझे एक अनुरक्षणीयता सूचकांक देता है 6 अंक में सुधार, और एक अच्छा धाराप्रवाह वाक्यविन्यास देता है। दूसरी तरफ मुझे एक स्थिर वर्ग जोड़ना है, यह सामान्य नहीं है।

किसी भी दृष्टिकोण के बारे में कोई विचार आपके पक्ष में होगा? या हो सकता है कि रखरखाव सूचकांक में सुधार के लिए linq प्रश्नों को दोबारा कैसे करें, इसके बारे में अलग-अलग विचार हो?

+3

मेट्रिक्स केवल एक उपाय है, लेकिन कभी भी लक्ष्य नहीं है। –

+0

मैं किसी भी रखरखाव सूचकांक की थोड़ी संदिग्ध हूं जो एक अस्पष्ट काला बॉक्स है। कम से कम चक्रवात जटिलता के साथ यह वास्तव में मापा जा रहा है कि स्थापित करने के लिए संभव है। क्या आपको पता है कि यह कहीं भी (नहीं) स्पष्टीकरण [http://msdn.microsoft.com/en-us/library/bb385914.aspx) से परे समझाया गया है? – AakashM

उत्तर

5

आपको मेट्रिक्स के लिए कक्षाएं नहीं जोड़नी चाहिए। कोई भी मीट्रिक आपके कोड बेहतर बनाने के लिए है, लेकिन नियमों का अंधाधुंध, यहां तक ​​कि सर्वोत्तम नियम, वास्तव में आपके कोड को नुकसान पहुंचा सकता है।

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

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

यह केवल मीट्रिक का पालन करना चाहिए है लेकिन यह हमेशा मीट्रिक हर किसी पर इस बात से सहमत नहीं है ...

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

मुझे यह भी समझ में नहीं आता कि आप क्यों कहते हैं, वे कुछ नकारात्मक अर्थों के साथ सामान्य नहीं हैं। आपको हर जगह जेनेरिक की जरूरत नहीं है! वास्तव में, विस्तार विधियों को लिखते समय, आपको उन विशिष्ट प्रकारों पर विचार करना चाहिए जिन्हें आप चुन सकते हैं क्योंकि अन्य वर्गों के विधि सेट को प्रदूषित नहीं किया जाता है। यदि आप चाहते हैं कि आपका सहायक केवल IEnumerable<MyType> के साथ काम करे, तो this IEnumerable<MyType> के लिए बिल्कुल एक एक्सटेंशन विधि घोषित करने में बिल्कुल शर्म की बात नहीं है। वैसे, आपके उदाहरण में अनावश्यक कास्टिंग है। से मुक्त होना।

और यह न भूलें, उपकरण बेवकूफ हैं। तो हम हैं, इंसान।

4

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

आपको लगता है कि आपके एप्लिकेशन के लिए सही क्या है?

+0

शायद मेरा प्रश्न ऐसा लगता है कि हम मेट्रिक्स के गुलाम हैं, जो मामला नहीं है। हम इसे मार्गदर्शन के लिए उपयोग कर रहे हैं, लेकिन यह सुनिश्चित करने के लिए कि हर संभव तरीके से आपके तरीके को यथासंभव बनाए रखने के तरीके के बारे में सोचने के लिए स्वयं को लक्ष्य उच्च निर्धारित करें। मेरे पास क्या उपयोग करना है इसके बारे में कुछ विचार हैं, लेकिन यह देखना चाहते हैं कि दूसरे इसके बारे में क्या सोचते हैं। – ChristiaanV

1

नहीं: इस मामले में मैं चक्रवात जटिलता को अनदेखा करूँगा - जो आपने मूल रूप से बेहतर था।

खुद से पूछें कि अधिक स्पष्टीकरण क्या है। यह:

List.Where(m => m.BeginTime >= selectionFrom && m.EndTime <= selectionTo) 

या इस:

List.FilterBy(selectionFrom, selectionTo); 

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

विस्तार विधियों में सारणी खंडों को सारणी करना जटिल परिस्थितियों के साथ समझ में आता है, जहां एक नज़र में न्याय करना आसान नहीं है, जो क्वेरी खंड बना रहा है।

+0

मैं आपकी स्थिति से सहमत हूं; सिर्फ यह ध्यान देने के लिए कि प्रश्न के अनुसार, यह परिवर्तन स्पष्ट रूप से चक्रवात जटिलता के बजाय * रखरखाव सूचकांक * में सुधार करता है। – AakashM

2

मैं एक के लिए विस्तार विधि रणनीति से सहमत हूं। मैंने कुछ हद तक असली दुनिया के ऐप्स में किसी समस्या के बिना इसका इस्तेमाल किया है।

मेरे लिए, यह केवल मेट्रिक्स के बारे में नहीं है, बल्कि कोड की पुनः उपयोगिता भी है। निम्नलिखित छद्म-उदाहरण देखें:

var x = _repository.Customers().WhichAreGoldCustomers(); 

var y = _repository.Customers().WhichAreBehindInPayments(); 

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

इसके अतिरिक्त, वे composable हैं:

var z = _repository.Customers().WhichAreGoldCustomers().WhichAreBehindInPayments(); 

IMHO इस एक जीत दृष्टिकोण है।

हमें एकमात्र समस्या का सामना करना पड़ा है कि एक रेसर्पर बग है जो कभी-कभी विस्तार विधियों के लिए इंटेलिजेंस पागल हो जाती है। आप ".Whic" टाइप करते हैं और यह आपको इच्छित एक्सटेंशन विधि चुनने देता है, लेकिन जब आप उस पर "टैब" करते हैं, तो यह कोड में कुछ अलग-अलग होता है, न कि आपके द्वारा चुने गए एक्सटेंशन विधि। मैंने इसके लिए रीशेपर से स्विचिंग पर विचार किया है, लेकिन ...नाह :)

+0

सच है, यही मुझे इसके बारे में भी पसंद है। – ChristiaanV

0

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

उदाहरण में आप मुझे एक और वर्णनात्मक विधि नाम चुन लिया दे। इस सवाल का भी सवाल है कि सीमा समावेशी या अनन्य है, अन्यथा यह ठीक दिखता है।

आप अपने सिस्टम में एक से अधिक ऑब्जेक्ट जिसके लिए एक तारीख होने की अवधारणा आम तो एक इंटरफेस है, शायद IHaveADate (या कुछ और पर विचार कर रहा है है, तो बेहतर :-)

public static IQueryable<T> WithinDateRange(this IQueryable<T> source, DateTime from, DateTime to) where T:IHaveADate 

(IQueryable दिलचस्प है। मैं डॉन ऐसा नहीं लगता कि IENumerable इसे शर्मिंदा कर सकता है जो शर्म की बात है। यदि आप डेटाबेस क्वेरीज़ के साथ काम कर रहे हैं तो यह आपके तर्क को अंतिम SQL सर्वर में दिखाई देने के लिए अनुमति दे सकता है जो कि अच्छा है। सभी के साथ संभावित गॉचा है LINQ अपने कोड निष्पादित नहीं कर रहा है कि जब आप इसे होने की)

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

public static IQueryable<T> WithinDateRange(this IQueryable<T> source, DateRange range) where T:IHaveADate 

तुम भी, यदि आप इसे की तरह लग रहा है,

public static IEnumerable<T> WithinDateRange(this IEnumerable<T> source, DateRange range, Func<DateTime,T> getDate) 

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

var filtered = myThingCollection.WithinDateRange(myDateRange, x => x.Date)