2008-09-09 8 views
9

मैंने वास्तव में Jeff's postSpartan Programming पर आनंद लिया। मैं मानता हूं कि इस तरह का कोड पढ़ने के लिए एक खुशी है। दुर्भाग्यवश, मुझे यकीन नहीं है कि यह काम करने के लिए एक खुशी होगी।स्पार्टन प्रोग्रामिंग

सालों से मैंने "एक-अभिव्यक्ति-प्रति-पंक्ति" अभ्यास के बारे में पढ़ा है और उसका पालन किया है। मैं अच्छी लड़ाई लड़ी और मेरी जमीन आयोजित जब कई प्रोग्रामिंग पुस्तकों की तरह उदाहरण कोड के साथ इस सलाह मुकाबला किया है: हाल ही में

while (bytes = read(...)) 
{ 
    ... 
} 

while (GetMessage(...)) 
{ 
    ... 
} 

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

ObjectA a = getTheUser(session.getState().getAccount().getAccountNumber()); 

निराशा होती है और पूरी तरह परिहार्य है: कि "रेखा 65" जो पढ़ता है पर एक NullPointer अपवाद का दावा उत्पादन से एक लॉग फ़ाइल हो रही है। उस कोड के साथ एक विशेषज्ञ को पकड़ने का छोटा जो "सबसे अधिक संभावना" ऑब्जेक्ट चुन सकता है जो शून्य था ... यह एक वास्तविक व्यावहारिक दर्द है।

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

मैं साफ होने की कोशिश करता हूं - लेकिन स्पष्ट रूप से मेरे कोड को छेड़छाड़ करने से निश्चित रूप से श्रमिक लगता है। यह आम तौर पर कोड को ब्राउज़ करने में आसान नहीं बनाता है - लेकिन यह वास्तव में काम में आ रहा है या मेरे या किसी और के कोड के माध्यम से कदम उठाने पर काम में आ गया है।

क्या शैली वकील है और क्या आप इसे व्यावहारिक अर्थ में तर्कसंगत बना सकते हैं?

उत्तर

7

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

तो:

ObjectA एक = getTheUser (।। Session.getState() getAccount() getAccountNumber());

एक अपराध के करीब है क्योंकि हम चूहे छेद नीचे 4 वस्तुओं रहे हैं।इसका मतलब उन वस्तुओं में से किसी एक में कुछ बदलना है, मुझे यह जानना है कि आपने इस विधि में इस पूरे ढेर को बुलाया है। क्या मुसीबत है।

बेहतर:

Account.getUser();

नोट यह प्रोग्रामिंग के अभिव्यक्तिपूर्ण रूपों के प्रति काउंटर चलाता है जो अब मॉकिंग सॉफ़्टवेयर के साथ वास्तव में लोकप्रिय हैं। वहां से व्यापार यह है कि आपके पास कसकर युग्मित इंटरफ़ेस है, और अभिव्यक्तिपूर्ण वाक्यविन्यास केवल इसका उपयोग करना आसान बनाता है।

+0

आप जिन धाराप्रवाह एपीआई के बारे में बात कर रहे हैं वे सामान्य रूप से राज्य के वस्तुओं के पेड़ (जैसे आपका पहला उदाहरण करता है) नहीं चलते हैं, बल्कि वे उसी ऑब्जेक्ट या नई आंतरिक वस्तुओं को राज्य को समाहित करते हैं। इसलिए जब वे एलओडी के पत्र का उल्लंघन करते हैं, तो वे अपनी भावना का उल्लंघन नहीं करते हैं। – kyoryu

+0

@Kyoryu, मैं आपके बयान से सहमत हूं, लेकिन सवाल प्रति पंक्ति 1 कथन पर केंद्रित था। धाराप्रवाह एपीआई अभी भी डीबग करने के लिए थोड़ा कठिन बना देता है क्योंकि आप एक ही लाइन पर कई संचालन निष्पादित कर रहे हैं। –

+1

मुझे आपकी बात पूरी तरह से मिलती है। अच्छे धाराप्रवाह इंटरफ़ेस वास्तव में एकाधिक, परमाणु कॉल होने की बजाय, एकल तार्किक कथन प्राप्त करने के लिए एक बेहतर तरीका के रूप में 'एकाधिक कथन' का उपयोग करते हैं। आपके उदाहरण के लिए, मैं यह भी तर्क दूंगा कि Account.GetUser() एक विशेष रूप से अच्छा उदाहरण नहीं है, क्योंकि आमतौर पर उपयोगकर्ता पर कार्य करेगा। मैं खाता देख सकता हूं। एक्टुअलऑपरेशन()।(अभी भी मुझे लगता है कि हम सामान्य रूप से सहमत हैं, हम 2% पर quibbling कर रहे हैं) – kyoryu

4

प्रति पंक्ति एक अभिव्यक्ति।

आपके कोड को खराब करने का कोई कारण नहीं है। अतिरिक्त समय टाइप करने में अतिरिक्त समय, आप डीबग समय में सहेजते हैं।

5

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

'मीठा स्थान' बीच में कहीं है।

3

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

2

मैं आमतौर पर "छोटा बेहतर बेहतर" शिविर में हूं। आपका उदाहरण अच्छा है:

ObjectA a = getTheUser(session.getState().getAccount().getAccountNumber()); 

अगर मैंने देखा की बजाय एक चार लाइनों है कि मैं चापलूसी होगा - मुझे नहीं लगता कि यह आसान पढ़ने के लिए या समझने के लिए बनाने चाहते हैं। जिस तरह से आपने इसे यहां प्रस्तुत किया है, यह स्पष्ट है कि आप एक ही वस्तु के लिए खुदाई कर रहे हैं। यह बेहतर नहीं है:

obja State = session.getState(); 
objb Account = State.getAccount(); 
objc AccountNumber = Account.getAccountNumber(); 
ObjectA a = getTheUser(AccountNumber); 

यह एक समझौता है:

objb Account = session.getState().getAccount(); 
ObjectA a = getTheUser(Account.getAccountNumber()); 

लेकिन मैं अभी भी एक लाइन अभिव्यक्ति पसंद करते हैं। यहां एक अचूक कारण है: मेरे लिए गूंगा टाइपो के लिए अभी 4-लाइनर को फिर से पढ़ना और त्रुटि-जांच करना मुश्किल है; एकल रेखा में यह समस्या नहीं है क्योंकि केवल कम वर्ण हैं।

+1

लेकिन अगर ऑब्जेक्ट ए के साथ एक NullPointerException उठाया जाता है एक = getTheUser (session.getState()। getAccount()। getAccountNumber()); ट्रेन में कौन सा ऑब्जेक्ट शून्य है? सत्र, राज्य, खाता, खाता संख्या या उपयोगकर्ता मूल funciton से वापस किया जा रहा है? – Ian

0

रखरखाव, और इसके साथ, पठनीयता, राजा है। सौभाग्य से, कम अक्सर मतलब अधिक पठनीय है।

  • चर नाम:

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

  • नियंत्रण प्रवाह: एक बार में कई बंद होने वाले खंडों (सी ++ में एक श्रृंखला) से बचें। आम तौर पर जब आप इसे देखते हैं, तो इससे बचने का एक तरीका है।

    if (things_are_ok) { 
        // Do a lot of stuff. 
        return true; 
    } else { 
        ExpressDismay(error_str); 
        return false; 
    } 
    

    द्वारा

    if (!things_are_ok) return ExpressDismay(error_str); 
    // Do a lot of stuff. 
    return true; 
    

    बदला जा सकता है अगर हम ExpressDismay प्राप्त कर सकते हैं (या एक आवरण क्या है) झूठी वापस जाने के लिए: एक आम मामले कुछ

  • तरह

है।

एक और मामला है:

  • लूप पुनरावृत्तियों: अधिक मानक, बेहतर। छोटे लूप के लिए, एक-वर्ण इटरेटर्स का उपयोग करना अच्छा होता है जब चर को कभी भी एक ऑब्जेक्ट में एक इंडेक्स के अलावा उपयोग नहीं किया जाता है।

विशेष मामले मैं यहाँ तर्क है "सही" जिस तरह से एक एसटीएल कंटेनर का उपयोग कर के खिलाफ है:

for (vector<string>::iterator a_str = my_vec.begin(); a_str != my_vec.end(); ++a_str) 

एक बहुत wordier है, और अतिभारित सूचक ऑपरेटरों * a_str या a_str-> आकार की आवश्यकता है() पाश में। कंटेनर कि तेजी से यादृच्छिक उपयोग कर सकते है के लिए, निम्न को पढ़ने के लिए बहुत आसान है:

for (int i = 0; i < my_vec.size(); ++i) 

संदर्भ के साथ my_vec को [i] पाश शरीर है, जो किसी को भी न समझ में।

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

0

अच्छा विवरण के साथ उन लोगों की ओर इनाम शिफ्ट करने की कोशिश होगी। मुझे लगता है कि यह सामान्य Divide and Conquer मानसिकता का संस्करण है।

2
ObjectA a = getTheUser(session.getState().getAccount().getAccountNumber()); 

यह एक बुरा उदाहरण है, शायद इसलिए कि आपने अभी अपने सिर के ऊपर से कुछ लिखा है। आप बताए जाते हैं प्रकार ObjectA की a नामित चर करने के लिए, एक समारोह के रिटर्न मान getTheUser नाम दिया है।
तो चलो मान लेते हैं तो आप इसके बजाए लिखा है:

User u = getTheUser(session.getState().getAccount().getAccountNumber()); 

मैं तो जैसे इस अभिव्यक्ति टूट जाएगा:

Account acc = session.getState().getAccount(); 
User user = getTheUser(acc.getAccountNumber()); 

मेरे तर्क है: मुझे लगता है मैं इस कोड के साथ क्या कर रहा हूँ के बारे में कैसे सोचते हैं?
मुझे शायद लगता है: "सबसे पहले मुझे सत्र से खाता प्राप्त करने की आवश्यकता है और फिर मैं उस खाते के नंबर का उपयोग कर उपयोगकर्ता को प्राप्त करूंगा"।

कोड तरह से आपको लगता है पढ़ना चाहिए। चर शामिल मुख्य इकाइयों को संदर्भित करना चाहिए; उनके गुणों के लिए इतना अधिक नहीं है (इसलिए मैं खाता संख्या को एक चर में संग्रहीत नहीं करता)।

मन में है के लिए एक दूसरा कारक है: मैंने कभी इस संदर्भ में फिर से इस इकाई का उल्लेख करने की आवश्यकता होगी?
यदि, कहें, मैं सत्र स्थिति से अधिक सामान खींच रहा हूं, तो मैं SessionState state = session.getState() पेश करूंगा।

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

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