क्या कोई फ़ंक्शन बहुत छोटा हो सकता है?


125

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

function conditionMet(){
   return x == condition;
}

या

function runCallback(callback){
   if($.isFunction(callback))
     callback();
}

क्या यह आलसी या बुरा व्यवहार है? मैं केवल इसलिए पूछता हूं क्योंकि इससे अधिक संख्या में फ़ंक्शन लॉजिक के बहुत छोटे टुकड़ों के लिए कॉल करते हैं।


3
नहीं, बहुत कम नहीं है। C # में मैं एक प्रॉपर्टी के रूप में 'कंडीशन मीट' करूंगा, जो एलिगेंट है, और उपयोग करने पर विचार करेगा Assert.AreEqual<int>(expected, actual, message, arg1, arg2, arg3, ...);। दूसरा जैसा है ठीक है। मैं संभावित रूप से एक वैकल्पिक बूल ध्वज शामिल करूंगा, जो यह अपवाद करेगा कि क्या अपवाद / आदि को फेंकना है। कॉलबैक एक कार्य नहीं है।
नौकरी '

38
हां, केवल एक मामले में: फंक्शन myFunction () {}
Spooks

5
def yes(): return 'yes'
डायटबुद्ध

3
@Spooks - मैं बंटवारे बाल यहाँ हूँ, लेकिन खाली कार्यों में कम से कम अनुकूलक वर्गों के लिए मान्य हैं में MouseMotionAdapter जैसे download.oracle.com/javase/6/docs/api/java/awt/event/... । बेशक यह भाषा की सीमाओं के आसपास काम करने का एकमात्र तरीका है।
अलेक्सी यर्थियाहो

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

जवाबों:


167

हे, ओह मिस्टर ब्राउन, अगर केवल मैं ही उन सभी डेवलपर्स को राजी कर सकता हूं जिन्हें मैं उनके कार्यों को छोटा रखने के लिए पूरा करता हूं, तो मेरा विश्वास करो, सॉफ्टवेयर की दुनिया एक बेहतर जगह होगी!

1) आपकी कोड पठनीयता दस गुना बढ़ जाती है।

2) पठनीयता के कारण अपने कोड की प्रक्रिया का पता लगाना इतना आसान है।

3) DRY - अपने आप को दोहराएं नहीं - आप इसे बहुत अच्छी तरह से समझ रहे हैं!

4) परीक्षण करने योग्य। टिनी फ़ंक्शंस उन 200 रेखा विधियों की तुलना में परीक्षण करने के लिए एक लाख गुना आसान हैं जिन्हें हम अक्सर देखते हैं।

ओह और प्रदर्शन के मामले में "फ़ंक्शन होपिंग" के बारे में चिंता न करें। "रिलीज" बिल्ड और कंपाइलर ऑप्टिमाइजेशन हमारे लिए बहुत अच्छी तरह से इसका ख्याल रखते हैं, और सिस्टम डिजाइन में कहीं और प्रदर्शन 99% है।

क्या यह आलसी है? - बहुत विपरीत!

क्या यह बुरा अभ्यास है? - बिलकुल नहीं। टार बॉल्स या "गॉड ऑब्जेक्ट्स" की तुलना में इस तरीके को बनाने के लिए बेहतर है कि ओह इतना आम है।

मेरे साथी शिल्पकार;


40
आप इस सवाल का जवाब नहीं दे रहे हैं, आप सिर्फ उस नियम का प्रचार कर रहे हैं जिसके अधिक चरम अनुप्रयोगों पर यहां सवाल उठाए गए हैं।

4
यह बहुत बार नहीं है कि मुझे निराशा होती है। लेकिन, इस जवाब के लिए, +1 इसे न्याय नहीं करता है।
बेवन

4
+5 ... ओह केवल +1 ही कर सकता है, ओह वेल! और मेशमैन का समर्थन करने के लिए, मैं रॉबर्ट सी। मार्टिन क्लीन कोड द्वारा निम्नलिखित पुस्तक का सुझाव देता हूं । यह पुस्तक वास्तव में अब मेरे कार्यक्रम के तरीके को बदल रही है।
एरिक-कार्ल

10
बहुत ही पसंद करने योग्य उत्तर, लेकिन मैं इसमें से अधिकांश से असहमत हूं: 1) अत्यधिक छोटे कार्यों के परिणामस्वरूप कुल मिलाकर अधिक कोड होते हैं, क्योंकि प्रत्येक फ़ंक्शन के लिए आवश्यक सभी नलसाजी हैं। यह पठनीयता को कम कर सकता है, विशेष रूप से वास्तव में बड़ी परियोजना के लिए। इसके अलावा, भाषा पर निर्भर। 2) पूरी तरह से बिंदु 1 पर निर्भर करता है, और इसलिए सवाल से कोई लेना-देना नहीं है। ३) क्या? runCallback चार बार "कॉलबैक" दोहराता है, और तीन बार एकल फ़ंक्शन को चलाने के लिए एक ही चर को संदर्भित करता है। 4) 200+ लाइन विधियां निश्चित रूप से परीक्षण योग्य नहीं हैं, लेकिन एक लाइन से उस तक लंबा रास्ता तय करना है।
l0b0

10
-1: यहां सबसे डरावनी बात इस जवाब के लिए दिए गए अप-वोटों की संख्या है।
लुका

64

मैं कहूंगा कि यदि कोई भी रिफैक्टेड तरीका बहुत छोटा हो तो:

  • यह एक आदिम ऑपरेशन की नकल करता है, किसी अन्य उद्देश्य के लिए इसे एक विधि बनाने के बजाय:

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

boolean isNotValue() {
   return !isValue();
}

या ...

  • कोड केवल एक बार उपयोग किया जाता है, और इसका आशय एक नज़र में समझना आसान है।

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

void showDialog() {
    Dialog singleUseDialog = new ModalDialog();
    configureDialog(singleUseDialog);
    singleUseDialog.show();
}

void configureDialog(Dialog singleUseDialog) {
    singleUseDialog.setDimensions(400, 300);
}

यह एक मान्य पैटर्न हो सकता है, लेकिन मैं इस उदाहरण में, configDialog () पद्धति को केवल इनलाइन करूंगा, जब तक कि मेरा इरादा इसे ओवरराइड करने या इस कोड को अन्यत्र पुन: उपयोग करने का न हो।


7
दूसरे मामले में सिंगल लाइन मेथड को अलग करना कॉलिंग एब्स्ट्रैक्शन लेवल को लगातार बनाए रखने के लिए फायदेमंद हो सकता है। यदि प्रदान किया गया उदाहरण बाड़ पर है तो इस तर्क का उपयोग किया जाता है: क्या सटीक पिक्सेल चौड़ाई और ऊंचाई एक संवाद दिखाने के लिए बहुत अधिक है?
एलेक्सी यर्थियाहो

2
"NotValue () "विधि बुरी तरह से नामित है और वास्तविक डोमेन प्रश्न का नाम देने के लिए इसे फिर से भरना चाहिए।

4
@ अलेक्सी: मैं असहमत हूं; विवरण पहले से ही इस उदाहरण में showDialog () विधि के भीतर छिपे हुए हैं; इसे डबल-रिफैक्टर करने की कोई आवश्यकता नहीं है। उदाहरण एक पृथक उपयोग के मामले को दिखाने के लिए है; यदि अलग-अलग मामलों में अलग-अलग संवाद विन्यास के साथ एक पैटर्न की आवश्यकता होती है, तो पैटर्न स्थापित होने के बाद वापस जाने और रिफ्लेक्टर करने का अर्थ होगा।
RMorrisey

1
@ थोरबॉर्न: मैं इसके लिए एक मामला देख सकता था, जब आप एक व्यावसायिक डोमेन प्रश्न का उत्तर दे रहे थे जिसका तर्क स्पष्ट नहीं हो सकता है। मैं सिर्फ इशारा कर रहा हूं कि ऐसे-ऐसे मामले हैं जहां यह ओवरकिल है।
RMorrisey

3
हो सकता है कि यह नाइटपैकिंग हो, लेकिन मैं तर्क दूंगा कि आपके उदाहरणों में समस्या यह नहीं है कि फ़ंक्शन बहुत छोटा है, लेकिन यह कि वे वर्णनात्मक मूल्य नहीं जोड़ते हैं।
कीपला

59

क्या कोई फ़ंक्शन बहुत छोटा हो सकता है? सामान्य तौर पर

वास्तव में यह सुनिश्चित करने का एकमात्र तरीका है:

  1. आपको अपने डिज़ाइन में सभी वर्ग मिल गए हैं
  2. आपके कार्य केवल एक ही कार्य कर रहे हैं।

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

इसे समझाने के लिए: एक फ़ंक्शन कार्यक्षमता का एक हिस्सा है जो चर द्वारा संवाद करता है। एक वर्ग भी कार्यशीलता के साथ एक गुंजाइश है जो चर द्वारा संवाद करता है। तो एक लंबे फ़ंक्शन को हमेशा एक या एक से अधिक कक्षाओं के साथ छोटे तरीके से प्रतिस्थापित किया जा सकता है।

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

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

Cleancoders.com पर क्लीन कोड के एपिसोड III में इसके बारे में बहुत कुछ है


5
अंकल बॉब! आपको यहाँ पर देखने के लिए बहुत अच्छा है। जैसी कि उम्मीद थी, शानदार सलाह। मैंने पहले कभी भी "एक्सट्रेक्ट टु द ड्रॉप" नहीं सुना है और निश्चित रूप से सोमवार को कार्यालय के चारों ओर इस शब्द का उपयोग किया जाएगा;)।
मार्टिन ब्लोर

1
क्या आप अपनी बात # 1 पर विस्तृत करने के लिए तैयार होंगे? यह बताते हुए कि उदाहरण से महान होगा।
डैनियल कपलान

53

वाह, इन जवाबों में से अधिकांश बहुत उपयोगी नहीं हैं।

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

अपने कार्य conditionMetऔर इस अन्य समारोह पर विचार करें , addOne(मुझे मेरी रसीली जावास्क्रिप्ट के लिए क्षमा करें):

function conditionMet() { return x == condition; }

function addOne(x) { return x + 1; }

conditionMetएक उचित वैचारिक परिभाषा है; addOneएक टॉटोलॉजी हैconditionMetअच्छा है क्योंकि आपको नहीं पता conditionMetकि "शर्त पूरी हुई" कहने से क्या होता है , लेकिन आप देख सकते हैं कि addOneअगर आप इसे अंग्रेजी में पढ़ते हैं तो यह मूर्खतापूर्ण क्यों है:

"For the condition to be met is for x to equal condition" <-- explanatory! meaningful! useful!

"To add one to x is to take x and add one." <-- wtf!

किसी भी चीज़ के प्यार के लिए जो अभी भी पवित्र हो सकती है, कृपया, टॉटोलॉजिकल फ़ंक्शन न लिखें!

(और इसी कारण से, कोड की प्रत्येक पंक्ति के लिए टिप्पणियां न लिखें !)


अधिक जटिल भाषा निर्माणों में से कुछ अपरिचित या पढ़ने में कठिन हो सकता है, जिससे यह एक उपयोगी चाल है।

3
सहमत, वास्तव में एक फ़ंक्शन में क्या बनाया जाना चाहिए यह काफी हद तक उस भाषा पर निर्भर करेगा जिसमें यह लिखा जा रहा है। AddOne जैसा एक फ़ंक्शन उपयोगी होगा यदि आप वीएचडीएल जैसी भाषा में थे, जहां आप वास्तव में एक पर एक जोड़ने के अर्थ को परिभाषित कर रहे हैं। बाइनरी या संख्या सिद्धांत स्तर। मैं यह सोचना चाहता हूं कि कोई भी भाषा इतनी गूढ़ नहीं है कि अभ्यास करने वाले प्रोग्रामर (शायद ब्रेनफ # ck) के लिए भी पढ़ना मुश्किल है, लेकिन अगर ऐसा है, तो यह विचार समान रूप से खड़ा होगा क्योंकि फ़ंक्शन अंग्रेजी से प्रभावी रूप से अनुवाद है। उस भाषा के लिए - तो नाम परिभाषा के समान नहीं है।
री मियाँसाका

1
मैं
हस्केल

1
@ मिस्सिंगो बाह, यह धोखा है: डी
री मियासाका

5
यदि आप उनकी सामग्री के बजाय उनके उद्देश्य से कार्यों को नाम देते हैं, तो वे तुरंत मूर्खतापूर्ण होना बंद कर देते हैं। तो आपके उदाहरण उदाहरण के लिए हो सकते हैं function nametoolong() { return name.size > 15; }या function successorIndex(x) { return x + 1; } इसलिए आपके कार्यों के साथ समस्या वास्तव में सिर्फ यह है कि उनका नाम खराब है।
हंस-पीटर स्टॉर्र

14

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

उदाहरण के लिए यदि आपका कोड दिखने वाला था:

if x == 1 { ... } // is pixel on?

इसके बजाय इसे इस तरह देखो:

if pixelOn() { ... }

साथ में

function pixelOn() { return x == 1; }

या दूसरे शब्दों में, यह विधि की लंबाई के बारे में नहीं है, बल्कि स्व-दस्तावेजीकरण कोड के बारे में है।


5
मेरे सम्मानित सहयोगी बताते हैं कि आप भी लिख सकते हैं if x == PIXEL_ON। एक निरंतर का उपयोग करना एक विधि का उपयोग करने के रूप में वर्णनात्मक हो सकता है, और थोड़ा सा दु: खद है।
टॉम एंडरसन

7

मुझे लगता है कि यह वही है जो आप करना चाहते हैं। अभी वह कार्य केवल एक या दो पंक्तियों का हो सकता है, लेकिन समय के साथ यह बढ़ सकता है। साथ ही अधिक फ़ंक्शन कॉल करने से आप फ़ंक्शन कॉल पढ़ सकते हैं और समझ सकते हैं कि वहां क्या हो रहा है। इससे आपका कोड बहुत DRY (अपने आप को दोहराएं नहीं) है जो बहुत अधिक बनाए रखने योग्य है।


4
तो बाद में इसे गलत साबित करने में क्या हर्ज है, जब आप यह साबित कर सकते हैं कि आपको जरूरत है, बजाय अब, जब यह सिर्फ मृत वजन है?
dsimcha

कार्य अपने आप नहीं बढ़ते हैं। IMHO उदाहरण घटिया हैं। conditionMetबहुत सामान्य नाम है, और कोई तर्क नहीं लेता है, इसलिए यह कुछ राज्य का परीक्षण करता है? (x == xCondition) अधिकांश भाषाओं और स्थितियों में 'xConditition' के रूप में अभिव्यंजक है।
उपयोगकर्ता अज्ञात

हां, और इसीलिए आप अपने कोड में 75% + ओवरहेड रखना चाहते हैं? 3 लाइन के रूप में लिखा गया सिंगर लाइनर वास्तव में 300% है।
कोडर

5

मैं अन्य सभी पदों से सहमत हूं जो मैंने देखे हैं। यह अच्छी शैली है।

ऐसी छोटी विधि का ओवरहेड शून्य हो सकता है क्योंकि ऑप्टिमाइज़र कॉल को दूर कर सकता है और कोड को इनलाइन कर सकता है। इस तरह का सरल कोड ऑप्टिमाइज़र को अपना सर्वश्रेष्ठ काम करने की अनुमति देता है।

स्पष्टता और सरलता के लिए कोड लिखा जाना चाहिए। मैं एक विधि को दो भूमिकाओं में से एक में सीमित करने का प्रयास करता हूं: निर्णय लेना; या प्रदर्शन कार्य। यह एक पंक्ति विधियाँ उत्पन्न कर सकता है। जितना बेहतर मैं यह कर रहा हूं, उतना ही बेहतर मुझे अपना कोड मिल रहा है।

इस तरह के कोड में उच्च सामंजस्य और कम युग्मन होता है जो अच्छा कोडिंग अभ्यास है।

EDIT: विधि नामों पर एक नोट। एक विधि नाम का उपयोग करें जो इंगित करता है कि विधि यह कैसे नहीं करती है। मुझे पता है कि verb_noun (_modifier) ​​एक अच्छी नामकरण योजना है। यह Select_Customer_Using_NameIdx के बजाय Find_Customer_ByName जैसे नाम देता है। दूसरा मामला गलत हो जाता है जब विधि को संशोधित किया जाता है। पहले मामले में, आप पूरे ग्राहक डेटाबेस कार्यान्वयन को स्वैप कर सकते हैं।


Inlining का उल्लेख करने के लिए +1, प्रदर्शन और छोटे कार्यों में मुख्य विचार को शामिल करें।
गार्ट क्लैबोर्न

4

एक फ़ंक्शन में कोड की एक पंक्ति को फिर से दिखाना अत्यधिक लगता है। ऐसे असाधारण मामले हो सकते हैं, जैसे कि ver loooooong / comples lines या expations, लेकिन मैं ऐसा नहीं करूंगा जब तक कि मुझे पता नहीं है कि भविष्य में फंक्शन बढ़ेगा।

और ग्लोबल्स के उपयोग पर आपका पहला उदाहरण संकेत देता है (जो कोड में अन्य मुद्दों की बात नहीं कर सकता है या नहीं), मैं इसे और अधिक परिष्कृत करूंगा, और उन दो चर को मापदंडों के रूप में बनाऊंगा:

function conditionMet(x, condition){
   return x == condition;
}
....
conditionMet(1,(3-2));
conditionMet("abc","abc");

conditionMetउदाहरण हो सकता है अगर हालत लंबे और दोहराव जैसे था उपयोगी हो:

function conditionMet(x, someObject){
   return x == ((someObject.valA + someObject.valB - 15.4) / /*...whole bunch of other stuff...*/);
}

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

7
यह conditionMetफ़ंक्शन सिर्फ एक क्रिया ==ऑपरेटर है। यह संभवतः उपयोगी नहीं है।

1
मैं निश्चित रूप से ग्लोबल्स का उपयोग नहीं करता हूं। @MeshMan, बिल्कुल वही उदाहरण है जहां से उदाहरण है ... एक वर्ग पर एक विधि।
मार्क ब्राउन

1
@ मार्क ब्राउन: @ मेशमैन: ठीक है, मुझे लगता है कि कोड उदाहरण बहुत अस्पष्ट था, यह सुनिश्चित करने के लिए ...
FrustratedWithFormsDesigner

मैं conditionMet (x, relation condition) {यहां से महक रहा हूं , जहां आप x, '==' और संबंध से गुजरते हैं। फिर आपको '<', '>', '<=', '! =' आदि के लिए कोड दोहराने की आवश्यकता नहीं है। दूसरी तरफ - अधिकांश भाषाओं में ये निर्माण ऑपरेटर (x == स्थिति) के रूप में निर्मित होते हैं। परमाणु कथनों के लिए कार्य एक कदम बहुत दूर है।
उपयोगकर्ता अज्ञात

3

इस पर विचार करो:

एक साधारण टक्कर का पता लगाने का कार्य:

bool collide(OBJ a, OBJ b)
{
    return(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) <= pow(a.radius + b.radius, 2));
}

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


यदि हम यहाँ C के साथ काम कर रहे हैं, तो हम दुरुपयोग कर सकते हैं #define;)
कोल जॉनसन

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

2

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


मैं इसे कोड की पंक्तियों में नहीं बल्कि भावों में गिनूंगा। "(x == स्थिति)" परमाणु है, इसलिए मैं इसे एक विधि / कार्य में लगाऊंगा, यदि इसका उपयोग कई बार किया जाता है और इसे बदला जा सकता है, function isAdult () = { age >= 18; }लेकिन निश्चित रूप से नहीं isAtLeast18
उपयोगकर्ता अज्ञात

2

मैं कहूंगा कि वे बहुत कम हैं, लेकिन यह मेरी व्यक्तिपरक राय है।

चूंकि:

  • एक फ़ंक्शन बनाने का कोई कारण नहीं है यदि यह केवल एक या दो बार उपयोग किया जाता है। डिम्पल्स को कूदना चूसना। विशेष रूप से आश्चर्यजनक तेज वीएस और सी ++ कोड के साथ।
  • कक्षा का अवलोकन। जब आपके पास हजारों छोटे कार्य होते हैं, तो यह मुझे गुस्सा दिलाता है। मुझे मजा आता है जब मैं कक्षा की परिभाषाएं देख सकता हूं और जल्दी से देख सकता हूं कि यह क्या करता है, न कि यह कैसे सेटएक्सटॉइन, सेटयूटोवेक्टर 3, मल्टीप्लेनेट्स, + 100 बसे / गेटर्स।
  • ज्यादातर प्रोजेक्ट्स में ये हेल्पर्स एक अयस्क के दो रीफैक्टरिंग चरणों के बाद डेड वेट हो जाते हैं, और फिर आप अप्रचलित कोड से छुटकारा पाने के लिए "सर्च ऑल" -> डिलीट करते हैं, आमतौर पर इसका ~ 25% +।

फ़ंक्शंस जो लंबे होते हैं वे खराब होते हैं, लेकिन फ़ंक्शंस जो कि 3 लाइनों से कम होते हैं और केवल 1 चीज़ करते हैं, समान रूप से खराब होते हैं IMHO।

तो मैं कहूंगा कि केवल छोटा कार्य लिखो अगर यह है:

  • कोड की 3+ लाइनें
  • सामान है कि जूनियर देवों को याद कर सकते हैं (पता नहीं)
  • अतिरिक्त सत्यापन करता है
  • का उपयोग किया जाता है, या कम से कम 3x उपयोग किया जाएगा
  • अक्सर उपयोग किए जाने वाले इंटरफ़ेस को सरल करता है
  • अगले रीफैक्टरिंग के दौरान एक मृत वजन नहीं बनेगा
  • कुछ विशेष अर्थ है, उदाहरण के लिए, टेम्पलेट विशेषज्ञता या कुछ और
  • क्या कुछ अलग-थलग नौकरी - कॉन्स्ट रेफरेंस, म्यूटेबल मापदंडों को प्रभावित करता है, प्राइवेट मेंबर रिट्रीवल करता है

मुझे यकीन है कि अगले डेवलपर (वरिष्ठ) के पास आपके सभी SetXToOne कार्यों को याद रखने की तुलना में बेहतर चीजें होंगी। तो वे बहुत जल्दी ही मृत वजन में बदल जाएंगे।


1

मुझे उदाहरण नहीं पसंद है। 1, ith जेनेरिक नाम का bcause।

conditionMetयह सामान्य नहीं लगता है, इसलिए यह एक विशिष्ट स्थिति के लिए खड़ा है? पसंद

isAdult () = { 
  age >= 18 
}

यह ठीक रहेगा। यह एक अर्थगत अंतर है, जबकि

isAtLeast18 () { age >= 18; } 

मेरे लिए ठीक नहीं होगा।

शायद इसका उपयोग अक्सर किया जाता है, और बाद में बदलाव के लिए विषय हो सकता है:

getPreferredIcecream () { return List ("banana", "choclate", "vanilla", "walnut") }

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

isXYZ (Foo foo) { foo.x > 15 && foo.y < foo.x * 2 }

परमाणु नहीं है, और आपको एक अच्छा परीक्षण अवसर देना चाहिए।

यदि आपको कोई फ़ंक्शन पास करने की आवश्यकता है, तो निश्चित रूप से, जो भी आपको पसंद है उसे पास करें, और अन्यथा मूर्खतापूर्ण कार्यों को लिखें।

लेकिन सामान्य तौर पर, मैं बहुत अधिक कार्य देखता हूं, जो बहुत लंबे हैं, उन कार्यों की तुलना में जो बहुत कम हैं।

एक अंतिम शब्द: कुछ कार्य केवल उचित लगते हैं, क्योंकि वे बहुत अधिक लिखित होते हैं:

function lessThan (a, b) {
  if (a < b) return true else return false; 
}

यदि आप देखते हैं, कि यह जैसा है वैसा ही है

return (a < b); 

आपको कोई समस्या नहीं होगी

localLessThan = (a < b); 

के बजाय

localLessThan = lessThan (a, b); 

0

कोई कोड जैसा कोई कोड नहीं है!

इसे सरल रखें और जटिल चीजों को खत्म न करें।

यह आलसी नहीं है, यह आपका काम कर रहा है!


0

हां, इसका संक्षिप्त कोड कार्य करना ठीक है। "गेटर्स", "सेटलर्स" के रूप में तरीकों के मामले में, "एक्सीसर्स" बहुत आम है, जैसा कि पिछले उत्तरों में उल्लेख किया गया है।

कभी-कभी, उन छोटे "accesors" फ़ंक्शन आभासी होते हैं, क्योंकि जब उपवर्गों में ओवरराइड किया जाता है, तो फ़ंक्शन में अधिक कोड होंगे।

यदि आप चाहते हैं कि आप इतने कम कार्य न करें, तो ठीक है, कई कार्यों में, वैश्विक या तरीकों से, मैं आमतौर पर एक प्रत्यक्ष परिणाम के बजाय एक "परिणाम" चर (पास्कल शैली) का उपयोग करता हूं, एक डिबगर का उपयोग करते समय यह बहुत उपयोगी है।

function int CalculateSomething() {
  int Result = -1;

   // more code, maybe, maybe not

  return Result;
}

0

बहुत कम कभी कोई समस्या नहीं है। छोटे कार्यों के कुछ कारण हैं:

पुनर्प्रयोग

उदाहरण के लिए, यदि आपके पास कोई फ़ंक्शन है, तो एक सेट विधि की तरह, आप यह सुनिश्चित करने के लिए मान सकते हैं कि पैरामीटर मान्य हैं। यह जाँच हर जगह की जानी चाहिए कि चर सेट है।

रख-रखाव

आप कुछ कथन का उपयोग कर सकते हैं जो आपको लगता है कि भविष्य में बदल सकते हैं। उदाहरण के लिए, अब आप एक कॉलम में एक सिंबल दिखाते हैं, लेकिन बाद में वह कुछ और (या बीप) में बदल सकता है।

वर्दी

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


0

जब आप किसी कोड सेक्शन को कोई नाम देते हैं, तो उसे अनिवार्य रूप से एक नाम देना होता है । यह कई कारणों से हो सकता है, लेकिन महत्वपूर्ण बिंदु यह है कि क्या आप इसे एक सार्थक नाम दे सकते हैं, जो आपके कार्यक्रम में शामिल हो। "AddOneToCounter" जैसे नाम कुछ भी नहीं जोड़ेंगे, लेकिन conditionMet()होगा।

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


0

नहीं, लेकिन यह बहुत अधिक हो सकता है।

याद रखें: कोड एक बार लिखा जाता है, लेकिन कई बार पढ़ा जाता है।

संकलक के लिए कोड न लिखें। इसे भविष्य के डेवलपर्स के लिए लिखें, जिन्हें आपके कोड को बनाए रखना होगा।


-1

हाँ प्रिय, कार्य छोटा और छोटा हो सकता है और यह अच्छा है या बुरा यह उस भाषा / रूपरेखा पर निर्भर करता है जिसका आप उपयोग कर रहे हैं।

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

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

सामान्य रूप से छोटे फ़ंक्शन में आपका विशाल कोड एक बहुत अच्छा तरीका है। आधुनिक रूपरेखा और भाषाओं में आप ऐसा करने के लिए बाध्य होंगे

data => initScroll(data)

ईएस 2017 जावास्क्रिप्ट और टाइपस्क्रिप्ट में एक अनाम फ़ंक्शन है

getMarketSegments() {
 this.marketService.getAllSegments(this.project.id)
  .subscribe(data => this.segments = data, error => console.log(error.toString()));
}

उपरोक्त कोड में आप 3 फ़ंक्शन घोषणा और 2 फ़ंक्शन कॉल देख सकते हैं यह टाइपस्क्रिप्ट के साथ कोणीय 4 में एक सरल सेवा कॉल है। आप इसे अपनी आवश्यकताओं के रूप में सोच सकते हैं

([] 0)
([x] 1)
([x y] 2)

ऊपर क्लोजर भाषा में 3 बेनामी कार्य हैं

(def hello (fn [] "Hello world"))

ऊपर एक क्लोजर में एक कार्यात्मक घोषणा है

तो हाँ FUNCTIONS उतना ही छोटा हो सकता है लेकिन अगर आपके जैसे कार्य हों तो यह अच्छा या बुरा है:

incrementNumber(numb) { return ++numb; }

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

चलो एक और उदाहरण लेते हैं

insertInArray(array, newKey) {
 if (!array.includes(newKey)) {
   array.push(newKey);
 }
}

जब कोणीय एचटीएमएल टेम्प्लेट के अंदर सरणियाँ खेलते समय उपरोक्त उदाहरण एक होना चाहिए। तो कभी-कभी आपको छोटे कार्य करने पड़ेंगे


-2

मैं इस समय दिए गए लगभग जवाब से असहमत हूं।

हाल ही में मुझे एक सहकर्मी मिला, जो सभी वर्गों के सदस्यों को निम्न की तरह लिखता है:

 void setProperty(int value){ mValue=value; }
 int getProperty() const { return (mValue); }

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

संभवतः प्रोग्रामर समग्र तर्क को याद करता है, भविष्य के परिवर्तनों के बारे में डरता है और कोड को फिर से भरने के बारे में।

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

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


6
एक्सेसर / म्यूटेटर विधियों को जोड़ने का एक अच्छा कारण है, जिसे आप "भविष्य के बारे में डर ... रिफैक्टिंग" के तहत संकेत देते हैं। लेकिन आप सही भी हैं कि यह कोड में मूल्य नहीं जोड़ता है। न तो आकार को कम करके (स्थानीय रूप से या विश्व स्तर पर) या बढ़ती पठनीयता। मेरे दिमाग में, यह जावा और JavaBeans सम्मेलन दोनों में खराब भाषा डिजाइन की बात करता है। यह एक ऐसा क्षेत्र है (कई में से) जहां C # ने स्वचालित रूप से प्रॉपर्टी सिंटैक्स के साथ दोनों चिंताओं को दूर करने के लिए भाषा को सफलतापूर्वक सुधार दिया है । एक जावा प्रोग्रामर के रूप में, मैं बुनियादी संरचना जैसी कक्षाओं के लिए आपकी कच्ची शैली से सहमत हूं ।
22

1
गेट्टर / सेटर फ़ंक्शंस अच्छे होते हैं, भले ही वे अभी जो कुछ करते हैं, वह एक चर को पढ़ा या लिखा जाए। एक व्यावहारिक मामले के रूप में, आप एक ऐसे परिदृश्य की कल्पना कर सकते हैं, जहां बाद में आप हर बार क्षेत्र में परिवर्तन होने पर स्क्रीन पर एक मूल्य प्रिंट करने का निर्णय लेते हैं, या यह जांचने के लिए कि क्या यह मूल्य मान्य है या नहीं। (शायद यह एक अंश के लिए एक भाजक है, और आप यह सुनिश्चित करने के लिए जांचना चाहते हैं कि यह शून्य नहीं है।)
री मियासाका

2
गेटर्स और सेटर काफी भयानक होते हैं, उनका वैध उपयोग नहीं होता है। यदि उनका उपयोग करना आवश्यक है, तो मैं इसे भाषा की विफलता मानता हूं।
कार्सन मायर्स

@ रे: बाहरी लोगों के मूल्य के लिए एक बाहरी वर्ग की जाँच करने की आवश्यकता क्यों होगी? यह फ़्रेक्शन क्लास के फूट () फंक्शन द्वारा किया जाना चाहिए या फ़्लैटर क्लास को null भाजक की जाँच करने के लिए एक isDiv अदृश्य () प्रदान करना चाहिए। गेटिंग / सेटर की आवश्यकता आमतौर पर एक कोड गंध होती है जो आपकी कक्षा में उच्च युग्मन और / या कम सामंजस्य (यानी खराब) होती है।
रेयान

@ लाइ क्या? मैंने कभी नहीं कहा कि बाहरी लोगों की जांच करने के लिए एक बाहरी वर्ग का उपयोग किया जाना चाहिए। मैं कह रहा हूं कि एक बाहरी वर्ग दुर्घटना से 0 तक की संख्या निर्धारित कर सकता है। वैधता की जांच करने का उद्देश्य बसने वालों में होता है कि उपभोक्ता कोड में किसी भी कीड़े को पहले पाए जाने के लिए प्रोत्साहित करना। एक अदृश्य () फ़ंक्शन प्रदान करना जिसे कॉल किया जा सकता है या नहीं भी किया जा सकता है, उस छोर तक काम नहीं करता है। और वास्तव में गेटर्स / सेटर की आवश्यकता कैसे इंगित करती है कि उच्च युग्मन है?
री मियासका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.