c++ - कोड डुप्लिकेशन के लिए कोई वैध कारण?




design language-agnostic (14)

मैं वर्तमान में एक बहुत पुरानी सी ++ परियोजना की समीक्षा कर रहा हूं और वहां बहुत सारे कोड डुप्लिकेशंस देख रहा हूं।

उदाहरण के लिए, 5 एमएफसी संदेश हैंडलर के साथ एक कक्षा है जिसमें प्रत्येक कोड की 10 समान रेखाएं हैं। या यहाँ और वहां एक बहुत विशिष्ट स्ट्रिंग परिवर्तन के लिए 5-लाइन स्निपेट है। कोड डुप्लिकेशंस को कम करना इन मामलों में कोई समस्या नहीं है।

लेकिन मुझे एक अजीब लग रहा है कि मैं कुछ गलत समझ रहा हूं और मूल रूप से इस नकल के लिए एक कारण था।

कोड डुप्लिकेट करने के लिए वैध कारण क्या हो सकता है?

https://code.i-harness.com


अनुभवहीन होने के अलावा, यही कारण है कि डुप्लिकेट कोड घटनाएं दिखाई दे सकती हैं:

ठीक से रिएक्टर करने के लिए कोई समय नहीं है

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

भाषा की बाधाओं के कारण कोड का सामान्यीकरण संभव नहीं है / नहीं 'सुंदर'

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

आप निश्चित नहीं हैं कि सामान्यीकरण होगा

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

अगर मुझे कुछ याद है तो मैं और जोड़ दूंगा।

बाद में जोड़ा गया ...

लूप अनोलिंग

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


आप यह सुनिश्चित करने के लिए ऐसा करना चाहेंगे कि एक हिस्से में भविष्य में परिवर्तन अनजाने में दूसरे भाग को नहीं बदलेगा। उदाहरण के लिए विचार करें

Do_A_Policy()
{
  printf("%d",1);
  printf("%d",2);
}

Do_B_Policy()
{
  printf("%d",1);
  printf("%d",2);
}

अब आप इस तरह के फ़ंक्शन के साथ "कोड डुप्लिकेशन" को रोक सकते हैं:

first_policy()
{
printf("%d",1);
printf("%d",2);
}

Do_A_Policy()
{
first_policy()
}

Do_B_Policy()
{
first_policy()
}

हालांकि एक जोखिम है कि कुछ अन्य प्रोग्रामर Do_A_Policy () को बदलना चाहते हैं और first_policy () को बदलकर ऐसा करेंगे और Do_B_Policy () को बदलने का दुष्प्रभाव पैदा करेंगे, जो एक साइड इफेक्ट है जिसे प्रोग्रामर के बारे में पता नहीं हो सकता है। इसलिए इस तरह के "कोड डुप्लिकेशन" कार्यक्रम में इस तरह के भविष्य के बदलावों के खिलाफ सुरक्षा तंत्र के रूप में कार्य कर सकते हैं।


इसके बारे में एक अच्छा पठन जॉन लेकोस द्वारा बड़े पैमाने पर सी ++ सॉफ्टवेयर डिजाइन है।

कोड कोड डुप्लिकेशन के बारे में उनके पास बहुत अच्छे अंक हैं, जहां यह किसी प्रोजेक्ट की मदद या बाधा डाल सकता है।

डुप्लिकेशंस या डुप्लिकेट कोड को हटाने का निर्णय लेने पर सबसे महत्वपूर्ण बिंदु पूछ रहा है:

यदि भविष्य में यह विधि बदलती है, तो क्या मैं डुप्लीकेट विधि में व्यवहार को बदलना चाहता हूं, या इसे जिस तरह से रहने के लिए जरूरी है?

आखिरकार, विधियों में (व्यवसाय) तर्क होता है, और कभी-कभी आप प्रत्येक कॉलर के लिए तर्क बदलना चाहते हैं, कभी-कभी नहीं। परिस्थितियों पर निर्भर करता है।

अंत में, यह सुंदर स्रोत के बारे में नहीं, रखरखाव के बारे में है।


उस तरह के कोड डुप्लिकेशन के लिए (कई बार लाइनों को कई बार डुप्लिकेट किया गया), मैं कहूंगा:

  • या तो आलस्य (आप यहां कुछ और कोड चिपकाते हैं, आवेदन के अन्य हिस्सों पर होने वाले किसी भी प्रभाव के बारे में चिंता किए बिना - एक नया कार्य लिखते समय और दो स्थानों पर इसका उपयोग करते हुए, मुझे लगता है कि कुछ प्रभाव पड़ सकता है)
  • या किसी भी अच्छे अभ्यास को नहीं जानते (कोड का पुन: उपयोग, विभिन्न कार्यों को अलग-अलग कार्यों / विधियों में अलग करना)

शायद पहला समाधान, हालांकि, मैंने जो देखा है उससे :-(

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

कोड को कई कार्यों में विभाजित करना, सही तरीके से कोड का उपयोग करना, और जो अक्सर अनुभव के साथ आते हैं - या आपने सही लोगों को नहीं रखा है ;-)


कभी-कभी विधियों और वर्गों में जो डोमेन-वार के समान नहीं हैं, लेकिन कार्यान्वयन-वार बहुत समान दिखता है। इन मामलों में कोड डुप्लिकेशंस करना अक्सर बेहतर होता है क्योंकि भविष्य में बदलाव अक्सर अधिक होता है जो इन कार्यान्वयनों को ऐसी चीज में नहीं डालता जो समान नहीं है।


कुछ ऐसा जो हमने पाया है कि हमें कोड डुप्लिकेट करने के लिए मजबूर किया गया था वह हमारे पिक्सेल मैनिपुलेशन कोड था। हम बहुत बड़ी छवियों के साथ काम करते हैं और फ़ंक्शन कॉल ओवरहेड हमारे प्रति-पिक्सेल समय के 30% के क्रम में खा रहा था।

पिक्सेल मैनिपुलेशन कोड को डुप्लिकेट करने से हमें कोड जटिलता की लागत पर 20% तेज छवि ट्रैवर्सल दिया गया।

यह स्पष्ट रूप से एक बहुत ही दुर्लभ मामला है, और अंत में यह हमारे स्रोत को काफी हद तक फहराता है (एक 300 लाइन फ़ंक्शन अब 1200 लाइनें है)।


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


जब मुझे सोर्स कोड जेनरेटर द्वारा उत्पादित किया जाता है तो मुझे डुप्लिकेट कोड के साथ कोई समस्या नहीं है।


बड़ी परियोजनाओं पर (एक जीबी के रूप में बड़े कोड कोड के साथ) मौजूदा एपीआई खोना काफी संभव है। यह आमतौर पर अपर्याप्त दस्तावेज, या मूल कोड का पता लगाने के लिए प्रोग्रामर की अक्षमता के कारण होता है; इसलिए डुप्लिकेट कोड।

आलस्य, या खराब समीक्षा अभ्यास के लिए उबाल जाता है।

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

एक अतिरिक्त संभावना यह है कि रास्ते में हटाए गए उन तरीकों में अतिरिक्त कोड हो सकता है।

क्या आपने फ़ाइल पर संशोधन इतिहास देखा है?


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

हालांकि, इस मामले में, मुझे नहीं लगता कि यही कारण है कि वे ऐसा कर रहे थे, हे।


मूल लेखक की तरह लगता है या तो अनुभवहीन था और / या समय पर कठिन दबाव डाला गया था। सबसे अनुभवी प्रोग्रामर उन चीज़ों को एक साथ जोड़ते हैं जिन्हें पुन: उपयोग किया जाता है क्योंकि बाद में कम रखरखाव होगा - आलस्य का एक रूप।

एकमात्र चीज जो आपको जांचनी चाहिए वह यह है कि यदि कोई साइड इफेक्ट्स है, तो कॉपी किए गए कोड में कुछ वैश्विक डेटा तक पहुंच होती है तो थोड़ा रिफैक्टरिंग की आवश्यकता हो सकती है।

संपादित करें: उस दिन वापस जब संकलक क्रोधित थे और ऑप्टिमाइज़र भी क्रैपीयर थे, ऐसा हो सकता है कि कंपाइलर में कुछ बग के कारण किसी को एक बग प्राप्त करने के लिए ऐसी चाल चलनी पड़ सकती है। शायद ऐसा कुछ ऐसा है? पुराना कितना पुराना है?


मेरी विनम्र राय में कोड डुप्लिकेशन के लिए कोई जगह नहीं है। उदाहरण के लिए, इस विकिपीडिया लेख पर एक नज़र डालें

या, लैरी वॉल के उद्धरण का संदर्भ लें:

"हम आपको प्रोग्रामर के तीन महान गुण विकसित करने के लिए प्रोत्साहित करेंगे: आलस्य, अधीरता, और हब्रिज।"

यह स्पष्ट है कि कोड डुप्लिकेशन के पास "आलस्य" से कोई लेना देना नहीं है। haha;)


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

उदाहरण (छद्म कोड):

procedure setPropertyStart(adress, mode, value)
begin
  d:=getObject(adress)
  case mode do
  begin
    single: 
       d.setStart(SingleMode, value);
    delta:
       //do some calculations
       d.setStart(DeltaSingle, calculatedValue);
   ...
end;

procedure setPropertyStop(adress, mode, value)
begin
  d:=getObject(adress)
  case mode do
  begin
    single: 
       d.setStop(SingleMode, value);
    delta:
       //do some calculations
       d.setStop(DeltaSingle, calculatedValue);
   ...
end;

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

संक्षेप में - अगर रिफैक्चरर्ड विधि कारकों को अधिक जटिल बनाती है, तो मैं कोड डुप्लिकेशन के साथ जाऊंगा हालांकि यह "बुरा" है (और बुराई रहेगा)।


सभी उत्तरों सही दिखते हैं, लेकिन मुझे लगता है कि एक और संभावना है। शायद प्रदर्शन विचार हैं क्योंकि जो चीजें आप कहते हैं उन्हें "कोड रेखांकित" की याद दिलाती है। उन्हें कॉल करने के लिए इनलाइन फ़ंक्शंस के लिए हमेशा तेज़ होता है। हो सकता है कि आप जिस कोड को देखते हैं वह पहले प्रीप्रोसेस्ड किया गया है?







code-duplication