2009-10-22 15 views
20

(की आप उन्हें बिल्कुल चाहिए सवाल अलग छोड़कर।)getters और setters शैली

मैं हमेशा बस दोनों गेटर और setters के लिए आप एक ही नाम देने के लिए अधिक भार समारोह का उपयोग करने के लिए पसंद है।

int rate() { return _rate; }  
void rate(int value) { _rate = value; } 

// instead of  
int getRate() { return _rate; }  
void setRate(int value) { _rate = value; } 

// mainly because it allows me to write the much cleaner  
total(period() * rate());  
// instead of  
setTotal(getPeriod() * getRate()); 

स्वाभाविक रूप से मैं सही हूं, लेकिन मुझे आश्चर्य हुआ कि लाइब्रेरी लेखकों के पास कोई अच्छा कारण था या नहीं?

+26

"स्वाभाविक रूप से मैं सही हूं" यह बहुत मजेदार है, मुझे उम्मीद है कि यह एक मजाक के रूप में था। –

उत्तर

30

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

इसके अलावा, जैसा अन्य लोगों ने बताया है, कुछ न करने का विकल्प

int Rate(); 
void SetRate(int value); 

कि सम्मेलन के साथ-साथ बहुत स्पष्ट है 'प्राप्त' और छोड़ 'set', यानी, पसंद करते हैं, मैं किसी भी नहीं होगा इसे पढ़ने में समस्या।

+2

अच्छा बिंदु। मान लें कि आपका कोड इस्तेमाल करने वाला व्यक्ति सिर्फ एक हास्यास्पद पागल नहीं है जो जानता है कि आप कहाँ रहते हैं, लेकिन यह थोड़ा उलझन में है! –

1

जबकि एड की टिप्पणी सच है, मैं सेटटर/गेटर एंटीपाटर पर वास्तविक गुण पसंद करता हूं। जब आपके डोमेन ग्राफ़ में 1/3 तरीके विधियां हैं जो ग्रहण द्वारा उत्पन्न की गई डमी विधियां हैं, तो कुछ गड़बड़ है।

प्रथम श्रेणी के गुणों के बिना, हालांकि, मेरा मानना ​​है कि एंटीपार्टर्न सबसे अधिक समझ में आता है।

इसके अलावा, यह कोड पूर्ण करने में आसान बनाता है।

setters
ही टिककर खेल

+0

यह एक "antipattern" क्यों है जब पहली कक्षा गुण एक ही चीज़ के लिए सिंटैक्टिक चीनी हैं? अवधारणा वही है, यह केवल कार्यान्वयन है कि अलग है। –

+0

यह इस अर्थ में एक एंटीपाटर है कि यह एक लाइनर हो सकता है। निजी संपत्ति int मूल्य; // अब आईओसी कंटेनर के साथ काम करता है; वाह। "मैं अपने सभी कार्यों के शीर्ष पर कोड की 30 लाइनों को दोहराता हूं। यह एक एंटीपार्टर्न कैसा है? कोड काम करता है!" –

+0

मुझे लगता है कि उसका मतलब है कि गेटर्स/सेटर्स होने पर एक विरोधी पैटर्न है - जो कि जरूरी नहीं है - jmucchiello –

5

मैं हमेशा छोड़ करने के लिए पसंद है obj.get (control shift space) के लिए obj.set (control shift space)rate() बजाय getRate() के साथ अपने ही टिककर खेल पर 'के लिए', जैसा कि आप करते हैं,। लेकिन सेटर के लिए ओवरलोडिंग मेरे लिए बहुत अच्छा विचार नहीं लगती है, क्योंकि rate नाम यह नहीं बताता है कि ऑब्जेक्ट को म्यूटेट किया जा रहा है। पर विचार करें:

total(period() * rate()); // awesome, very clear 

rate(20); // Looks like it computes a rate, using '20'...but for what? And why ignore the return value? 
+0

पर मेरी टिप्पणी देखें यह क्यूटी और जावा शैली है। http://qt.gitorious.org/qt/pages/ApiDesignPrinciples ---> goto "नामकरण की कला" –

6

कैसे int rate(); के बारे में और void setRate(int value);? इसमें अलग-अलग चीजों के समान नाम के दो कार्य नहीं होने का गुण है, और अभी भी period() * rate() की अनुमति देता है।

+1

शायद लोगों के साथ भ्रम पैदा करेगा जो getXXX –

+0

की तलाश में है यह क्यूटी और जावा शैली है। http://qt.gitorious.org/qt/pages/ApiDesignPrinciples ---> goto "नामकरण की कला" –

5

कुछ साल पहले, मैं पूरी तरह से सहमत होता। हाल ही में, एक संदेह अपना रास्ता बनाना शुरू कर दिया, क्योंकि इससे गेटटर या सेटर अस्पष्ट का पता लग जाता है। Tr1 :: bind जैसे टूल के साथ, यह वास्तव में कष्टप्रद है।

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

struct A 
{ 
    void Foo(int); 
    int Foo()const; 
}; 

std::vector<A> v = ....; 
std::vector<int> foos; 
// Extract Foo 
std::transform(
    v.begin(), v.end(), 
    std::back_inserter(foos), 
    //Ambiguous 
    // std::tr1::bind(&A::Foo) 
    //must write this instead. Yuck! 
    std::tr1::bind(static_cast<int(Foo::*)()>(&A::Foo)); 
); 

की आप उन सभी ;-)

+0

बाइंड() और इससे भी बदतर bind2nd() चीजें हैं जो मुझे चीज बनाती हैं C++ को अविश्वसनीय रूप से टूटा हुआ है। किसी भी इंसान को उचित रूप से पार्स करने की उम्मीद नहीं की जा सकती है, अकेले लिखने दें, कोड की उस पंक्ति को सही ढंग से लिखें! –

+1

अच्छा बिंदु। ओवरलोडिंग अपने आप पर अच्छा है, लेकिन जब आप फ़ंक्शन पते लेना शुरू करना चाहते हैं तो यह उस तरह से मिलता है। - @ एमजीबी: साथी इंसानों को कम मत समझो। कोई भी 'std :: mem_fun_ref' का उपयोग कर सकता है, लेकिन फिर से अधिभार के कारण, प्रकारों को निर्दिष्ट किया जाना चाहिए: 'std :: mem_fun_ref (& A :: Foo)'। – UncleBens

4

पर है चाहिए मैं आगे जाना है और यह उल्लेख एक समुदाय विकी सवाल होना चाहिए हूँ सवाल अलग छोड़कर।

जब मैं सी सीखने शुरू कर दिया ++ मैं शैली गाइड के लिए देखा है, और गूगल के कुछ बिंदुओं के लिए अच्छा था: अपरकेस में

  • तरीके (यह सिर्फ खूबसूरत है)।
  • गेटर्स सादे और लोकेसेज़ (rate)।
  • सेटर्स स्पष्ट रूप से और लोअरकेस (setRate)।
+0

ठीक है - यह सिर्फ एक निष्क्रिय कॉफी ब्रेक तरह का विचार था। –

2

संक्षेप होना महत्वपूर्ण है, लेकिन अपूर्ण या भ्रामक होने की लागत पर नहीं। इसी कारण से, मैं GetFoo() और SetFoo() को Foo() और Foo (int foo) पसंद करता हूं।

1

व्यक्तिगत रूप से, मुझे लगता है कि जोड़ों में पाए गए गेटर्स और सेटर्स "दृश्य" भाषाओं और उनके "गुणों" से प्राप्त कोड गंध हैं। एक "अच्छी" कक्षा में, डेटा सदस्य लिखित रूप से या पढ़ा जाता है लेकिन पढ़ नहीं/लिखते हैं।

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

शायद अपवाद हैं लेकिन मुझे बस एक कक्षा को देखने से नफरत है और "getX/setX, getY/setY, आदि इत्यादि" ढूंढना नफरत है। ऐसा लगता है कि वर्ग को इस्तेमाल करने के बारे में पर्याप्त विचार नहीं था और लेखक ने डेटा को प्राप्त करने के लिए कक्षा को आसान बना दिया ताकि उसे इस बात पर विचार नहीं करना पड़े कि कक्षा का उपयोग कैसे किया जाना चाहिए।

स्वाभाविक रूप से मैं सही हूं।

+0

एक 3 डी बिंदु प्रकार के बारे में सोचो। इसमें विभिन्न गणित सामग्री करने के लिए बहुत सारे आंतरिक कार्य होंगे, लेकिन आखिरकार सभी 6 प्राप्त/सेट x/y/z फ़ंक्शन की आवश्यकता होगी। –

+0

@ एमजीबी: व्यक्तिगत रूप से मुझे विश्वास नहीं है कि 3 डी पॉइंट प्रकार को सदस्यों को पहली जगह छिपाना चाहिए (शायद सिवाय इसके कि आप आंतरिक प्रतिनिधित्व के रूप में किसी सरणी का उपयोग करना चाहें)। – UncleBens

2

कई स्तरों रहे हैं करने के लिए "हो रही है" और "स्थापना"

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

तो हो जाओ/सेट एक उपयोगी अर्थ जिम्मेदार माना जा सकता है और हो सकता है एक बड़ी, लगातार नामकरण रणनीति का हिस्सा।

0

मैं उस सम्मेलन को लागू करता हूं जिसमें एक विधि हमेशा एक क्रिया होनी चाहिए और कक्षा हमेशा एक संज्ञा होनी चाहिए (स्पष्ट कारणों से मज़दूरों को छोड़कर)। इस स्थिति में, स्थिरता के लिए एक प्राप्त/सेट उपसर्ग का उपयोग किया जाना चाहिए। उस ने कहा, मैं पूरी तरह से एड Swangren के साथ सहमत हैं। यह उन उपसर्गों को नो-ब्रेनर का उपयोग करने के रूप में मेरे लिए बताता है।

1

किसी और मुद्दे का उल्लेख नहीं किया गया है फ़ंक्शन ओवरलोडिंग का मामला है। इस (काल्पनिक और अधूरा) उदाहरण लें:

class Employee { 
    virtual int salary() { return salary_; } 
    virtual void salary(int newSalary) { salary_ = newSalary; } 
}; 

class Contractor : public Employee { 
    virtual void salary(int newSalary) { 
     validateSalaryCap(newSalary); 
     Employee::salary(newSalary); 
    } 
    using Employee::salary; // Most developers will forget this 
}; 

कि using खंड के बिना, Contractor के उपयोगकर्ताओं अधिभार की वजह से वेतन क्वेरी नहीं कर सकता। मैंने हाल ही में एक परियोजना के चेतावनी सेट पर जोड़ा है, और देखो और देखो, यह पूरे स्थान पर दिखाई देता है।

+0

आप एमएसवीसी के लिए वर्चलोड-वर्चुअल के बराबर नहीं जानते हैं? –

+1

@ ग्रेग क्षमा करें, मैं नहीं करता हूं। मुझे वास्तव में एमएसवीसी की चेतावनियां (वीसी 8 के रूप में) ज्यादातर काउंटर-उत्पादक (बूल और इंट? स्ट्रक्चर के बीच रूपांतरण के लिए प्रदर्शन चेतावनी के रूप में पहले से घोषित किया गया है?) क्योंकि मैं दो प्लेटफार्मों पर निर्माण करता हूं, इसलिए मैं आमतौर पर सभी मेरे लिए जीसीसी पर भरोसा करता हूं चेतावनी की जरूरत है। – Tom

0

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

आप मुद्दों हो सकता है:

class Stuff { 
    void widget(int something); // 'special' setter 
    const Widget& widget(int somethingelse) const; // getter 
} 
Stuff a; 
a.widget(1); // compiler won't know which widget you mean, not enough info 
+2

आप कंपाइलर के लिए सार्थक नाम नहीं लिखते हैं, आप इसे साथी प्रोग्रामर के लिए करते हैं जिसे आपके कोड का उपयोग करना पड़ता है। – Triskeldeian

+0

कृपया यह न सोचें कि छोटे/चालाक/संक्षिप्त कोड लिखना किसी भी तरह से स्वचालित रूप से बेहतर है। कोड लिखें ताकि आप और आपके साथियों को पता चले कि 6 महीने बाद आपके बालों को खींचने के बिना क्या चल रहा है। – nenchev

0

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

यह स्पष्ट रूप से व्यक्तिपरक है और यह मेरी निजी वरीयता है।

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