क्लास विधि परिभाषाओं को क्रमबद्ध करने के लिए अधिकांश मानव-अनुकूल तरीका?


38

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

  1. आदेश मायने रखता है?
  2. क्या कोई "सर्वश्रेष्ठ" आदेश है?
  3. मुझे लगता है कि वहाँ नहीं है, इसलिए पेशेवरों और विभिन्न आदेश रणनीतियों के विपक्ष क्या हैं?

1
आप वास्तव में लोगों को कोड को काटने / पेस्ट करने की उम्मीद नहीं करते हैं, बस तरीकों को फिर से बनाने के लिए। अगर आईडीई स्वचालित रूप से करता है, तो ठीक है। अन्यथा, इसे लागू करना कठिन है।
रिएक्टगुलर

स्पष्ट करने के लिए, मेरा प्रश्न पठनीयता / उपयोगिता के बारे में है, वाक्य रचना के बारे में नहीं।
जॉनट्रॉन

जवाबों:


52

कुछ प्रोग्रामिंग भाषाओं में, ऑर्डर मायने रखता है क्योंकि आप घोषित होने के बाद तक चीजों का उपयोग नहीं कर सकते हैं। लेकिन ज्यादातर भाषाओं के लिए, यह संकलक के लिए कोई फर्क नहीं पड़ता। तो फिर, आप इसे मनुष्यों के लिए छोड़ रहे हैं।

मेरा पसंदीदा मार्टिन फाउलर उद्धरण है: Any fool can write code that a computer can understand. Good programmers write code that humans can understand.इसलिए मैं कहूंगा कि आपकी कक्षा का क्रम इस बात पर निर्भर होना चाहिए कि मनुष्य के लिए इसे समझना कितना आसान है।

मैं व्यक्तिगत रूप से स्टेप-डाउन उपचार पसंद करता हूं जो बॉब मार्टिन ने अपनी Clean Codeपुस्तक में दिया है । सदस्य वर्ग के शीर्ष पर चर, फिर कंस्ट्रक्टर, फिर अन्य सभी तरीके। और आप तरीकों को एक साथ बंद करने का आदेश देते हैं कि वे कक्षा के भीतर कैसे उपयोग किए जाते हैं (बल्कि सभी सार्वजनिक और फिर निजी रूप से संरक्षित हैं)। वह इसे "वर्टिकल डिस्टेंस" या ऐसा कुछ कहना (इस समय मेरे पास पुस्तक नहीं है) को कम से कम कहते हैं।

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

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

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

तो यहाँ एक वंचित उदाहरण है जो कई मायनों में खराब है (खराब ओओ डिज़ाइन; कभी भी doubleपैसे के लिए उपयोग न करें ) लेकिन विचार को दिखाता है:

public class Employee {
  ...
  public String getEmployeeId() { return employeeId; }
  public String getFirstName() { return firstName; }
  public String getLastName() { return lastName; }

  public double calculatePaycheck() {
    double pay = getSalary() / PAY_PERIODS_PER_YEAR;
    if (isEligibleForBonus()) {
      pay += calculateBonus();
    }
    return pay;
  }

  private double getSalary() { ... }

  private boolean isEligibleForBonus() {
    return (isFullTimeEmployee() && didCompleteBonusObjectives());
  }

  public boolean isFullTimeEmployee() { ... }
  private boolean didCompleteBonusObjectives() { ... }
  private double calculateBonus() { ... }
}

तरीकों का आदेश दिया जाता है इसलिए वे उन लोगों के करीब होते हैं जो उन्हें कॉल करते हैं, ऊपर से नीचे हमारे तरीके से काम करते हैं। यदि हमने सभी privateविधियाँ नीचे रख दी publicहैं, तो आपको कार्यक्रम के प्रवाह का पालन करने के लिए और अधिक कूदना होगा।

getFirstNameऔर getLastNameवैचारिक रूप से संबंधित हैं (और getEmployeeIdशायद बहुत अधिक हैं), इसलिए वे एक साथ करीब हैं। हम उन सभी को नीचे तक ले जा सकते हैं, लेकिन हम getFirstNameशीर्ष getLastNameपर और नीचे देखना नहीं चाहेंगे ।

उम्मीद है कि यह आपको मूल विचार देता है। यदि आप इस तरह की चीज में रुचि रखते हैं, तो मैं दृढ़ता से पढ़ने की सलाह देता हूं Clean Code


मुझे यह जानने की जरूरत है कि किस तरह से बसे और गेट वेरिएबल के गेटर्स को रखा जाना चाहिए। क्या यह क्लास कंस्ट्रक्टर के ठीक बाद या क्लास के निचले हिस्से में आना चाहिए?
श्रीनिवास

व्यक्तिगत रूप से मैं उन्हें कंस्ट्रक्टर के बाद शीर्ष पर पसंद करता हूं। लेकिन यह वास्तव में मायने नहीं रखता; मैं आपकी परियोजना और आपकी टीम के साथ निर्णय लेने के लिए एक अच्छे तरीके के रूप में निरंतरता की सिफारिश करूंगा।
एलन

calculateBonus()पहले नहीं आना चाहिए isFullTimeEmployee()और didCompleteBonusObjectives()?
winklerrr

@winklerrr मैं इसके लिए एक तर्क देख सकता हूं। मैंने उन्हें वहाँ रखा जहाँ मैंने ऐसा किया था isFullTimeEmployeeऔर इसलिए उनका didCompleteBonusObjectivesउपयोग किया जाता है, क्योंकि उन्हें isEligibleForBonusइसके करीब होना चाहिए। लेकिन आप संभावित calculateBonusरूप से इसे जहां कहा जाता है, उसके करीब लाने के लिए आगे बढ़ सकते हैं । दुर्भाग्यवश, जब आपके पास फ़ंक्शन कॉलिंग फ़ंक्शन होते हैं, तो आप अंत में मुद्दों के साथ समाप्त होते हैं (जैसे एक साझा कार्यों को कई अन्य लोगों द्वारा बुलाया जाता है) जहां एक परिपूर्ण ऑर्डर नहीं है। फिर यह आपके सर्वोत्तम निर्णय पर छोड़ दिया जाता है। मैं उन समस्याओं को कम करने के लिए कक्षाओं और कार्यों को छोटा रखने की सलाह देता हूं।
एलन

2

मैं आम तौर पर अपने तरीकों का संबंध और उपयोग के क्रम से आदेश देता हूं।

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

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

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

इस तरह से यह विशेष रूप से एक तीसरे पक्ष को देखने / आपके कोड को अपने समूह के रूप में उपयोग करने के लिए समझ में आता है और इसका उपयोग किए जाने वाले आदेश का पालन करेगा, इसलिए वे जिस कोड को आपकी कक्षा के साथ लिखेंगे, वह कक्षा के समान संरचना का पालन करेगा।

जैसा कि संबंध है?

पठनीयता के लिए, निश्चित रूप से।

इसके अलावा वास्तव में नहीं, केवल उन मामलों में जहां कुछ भाषाएं आप उस विधि को नहीं कह सकती हैं जब तक कि इसके ऊपर परिभाषित नहीं किया जाता है जहां इसके नाम आदि।


0

आदर्श रूप से, आपकी कक्षाएं इतनी छोटी हैं कि इससे कोई फर्क नहीं पड़ता। यदि आपके पास केवल एक दर्जन विधियां हैं, और आपका संपादक या आईडीई तह का समर्थन करता है, तो आपको कोई समस्या नहीं है, क्योंकि विधियों की पूरी सूची 12 लाइनों में फिट होती है।

ऐसा करने में, शीर्ष-स्तरीय अंतर सार्वजनिक बनाम निजी होना चाहिए। पहले सार्वजनिक तरीकों को सूचीबद्ध करें: ये वे हैं जो लोग सबसे अधिक तलाश करने वाले हैं, क्योंकि वे आपके कोडबॉर्स के बाकी हिस्सों के साथ जिस तरह से परिभाषित करते हैं।

फिर, इनमें से प्रत्येक के अंदर, यह कार्यक्षमता द्वारा समूह विधियों के लिए सबसे अधिक समझ में आता है: एक ब्लॉक में कंस्ट्रक्टर और विध्वंसक, दूसरे में गेटर्स / सेटर, ऑपरेटर ओवरलोड, स्थिर तरीके और शेष गुच्छा। C ++ में, मैं operator=हालांकि कंस्ट्रक्टरों के करीब रहना पसंद करता हूं , क्योंकि यह कॉपी कंस्ट्रक्टर से निकटता से संबंधित है, और इसलिए भी कि मैं जल्दी से हाजिर होना चाहता हूं कि क्या डिफॉल्ट ctor, copy ctor, operator = और dtor के सभी (या कोई नहीं) मौजूद।


-1

tl; डॉ

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


1 है। आदेश मायने रखता है?

केवल तभी यदि आप जिस भाषा में काम कर रहे हैं, उसे फ़ाइल में पहले से परिभाषित एक फ़ंक्शन की आवश्यकता होती है, जहां इसे कहा जाता है, जैसे कि इस उदाहरण में:

void funcA()
{
   funcB();
}

void funcB()
{
   //do something interesting...
}

आपके द्वारा funcB()उपयोग करने से पहले कॉल करने पर आपको एक त्रुटि मिलेगी । मुझे लगता है कि यह पीएल / एसक्यूएल और संभवतः सी में एक मुद्दा है, लेकिन आपके पास आगे की घोषणाएं हो सकती हैं जैसे:

void funcB();

void funcA()
{
   funcB();
}

void funcB()
{
   //do something interesting...
}

यह एकमात्र ऐसी स्थिति है जिसके बारे में मैं सोच सकता हूं कि यदि आदेश "गलत" है, तो आप संकलन भी नहीं कर पाएंगे।

अन्यथा, आप हमेशा उन्हें फिर से ऑर्डर कर सकते हैं, हालांकि आप चाहते हैं। आप शायद आपके लिए ऐसा करने के लिए एक टूल भी लिख सकते हैं (यदि आप वहां से बाहर नहीं निकल सकते हैं)।

२। क्या कोई "सर्वश्रेष्ठ" आदेश है?

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

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

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