उचित डिज़ाइन द्वारा आसान किए जाने के लिए कौन से परिवर्तन बहुत बड़े हैं?


11

यह एक अस्पष्ट प्रश्न है, लेकिन यह कुछ ऐसा है जिसे मैंने कभी महसूस नहीं किया है जब उचित डिजाइन के बारे में पढ़कर संतोषजनक तरीके से उत्तर दिया गया हो।

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

अपेक्षाकृत छोटे बदलावों के लिए, इसने मेरे लिए अच्छा काम किया है। प्रदर्शन को बढ़ाने के लिए एक वर्ग द्वारा उपयोग किए जाने वाले आंतरिक डेटा संरचनाओं में परिवर्तन कभी भी एक बड़ी कठिनाई नहीं रही है, और न ही उपयोगकर्ता-इंटरफ़ेस के अंत में परिवर्तन हुए हैं, एपीआई से स्वतंत्र, जैसे कि एक पाठ प्रविष्टि प्रणाली को फिर से डिज़ाइन करना या गेमप्ले तत्व के लिए ग्राफिक्स को ओवरहाल करना। ।

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

हालांकि, जब भी परिवर्तन बड़े और बालों वाले होते हैं - अर्थात, एपीआई में परिवर्तन - मेरे कीमती "पैटर्न" में से कोई भी कभी बचाव में नहीं आता है। बड़ा परिवर्तन बड़ा रहता है, प्रभावित कोड प्रभावित रहता है, और बग-स्पोविंग कार्य के कई घंटे मेरे आगे पड़े रहते हैं।

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

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

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


मैं यह नहीं देखता कि आपकी भाषा में परिवर्तन किसी भी चीज़ को कैसे छूता है लेकिन पार्सर। क्या आप इसे स्पष्ट कर सकते हैं?
स्कारफ्रिज

एक में smalltalk जैसी भाषा, यह सच है कि आप केवल क्योंकि यह इलाज का एक सरल बात होगी, पार्सर संशोधित करने की आवश्यकता होगी foo metarg1: bar metarg2: bazके रूप में foo.metarg1_metarg2_(bar, baz)। हालाँकि, मेरी भाषा एक बड़ा बदलाव कर रही है, अर्थात् सूची आधारित मापदंडों को शब्दकोश आधारित मापदंडों के लिए, जो रनटाइम को प्रभावित करता है लेकिन पार्सर को नहीं , वास्तव में, मेरी भाषा के विशिष्ट गुणों के कारण मैं अभी इसमें नहीं जाऊंगा। चूंकि अनियंत्रित-कीवर्ड और स्थिति संबंधी तर्कों के बीच कोई स्पष्ट मानचित्रण नहीं है, इसलिए रनटाइम मुख्य मुद्दा है।
१३'१३

जवाबों:


13

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

यही कारण है कि मुझे लगता है कि प्रत्येक प्रोग्रामर को 24/7 उत्पादन वातावरण के लिए एक स्टिंट लेखन सॉफ्टवेयर करना चाहिए। प्रति मिनट अपने वार्षिक वेतन के आदेश पर उद्धृत नुकसान के बारे में कुछ है जो आपको मजबूत प्रवासन कोड लिखने के लिए सीखने के लिए प्रेरित करता है।

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

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

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

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


नए मामले और पुराने मामले का समर्थन करने के लिए +1 ताकि आप जाते ही चरणबद्ध हो सकें।
एरिक रेपेन

9

मैं आपको मड निबंध की बिग बॉल पढ़ने की सलाह दूंगा।

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

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

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

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


1
+1: उपन्यास अपफ्रंट डिज़ाइन शायद ही कभी सफल होता है। सफल डिज़ाइन या तो सिद्ध डिज़ाइनों के पुनर्पूंजीकरण हैं, या पुनरावृत्त रूप से परिष्कृत किए गए हैं।
केविन क्लाइन

1
+1 आपको सभी प्रोग्रामिंग अवधारणाओं पर संदेह होना चाहिए , केवल उद्देश्य आलोचना के माध्यम से हम केवल समाधान के बजाय सही समाधान खोजने के लिए अपने विश्लेषणात्मक कौशल को लागू करते हैं
जिमी हॉफ

4

सामान्य शब्दों में, "टुकड़ों के कोड" (फ़ंक्शन, विधियां, ऑब्जेक्ट्स, जो भी हो) और "कोड के टुकड़ों के बीच इंटरफेस" (एपीआई, फ़ंक्शन घोषणाएं, जो भी हो; व्यवहार सहित)।

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

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

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


OOP का एक अन्य लाभ यह है कि इस पर चलने वाले तर्क के साथ डेटा को इनकैप्सुलेट करने से छोटे सार्वजनिक इंटरफेस (यदि अच्छा किया जाता है) होता है।
माइकल बोर्गवर्ड

2

कोई भी डिजाइन कार्यप्रणाली नहीं है जो आपको एक बड़ी आवश्यकताओं / गुंजाइश परिवर्तन की परेशानियों से बचा सके। यह असंभव है कि सभी संभावित परिवर्तनों की कल्पना करें और बाद में सोचा जा सके।

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

संक्षेप में, सभी बदलावों को एक अच्छे डिज़ाइन द्वारा आसान बनाया जाता है, लेकिन अच्छा डिज़ाइन एक बड़े बदलाव को छोटे में नहीं बदल सकता। (दूसरी ओर एक बुरा / कोई भी डिज़ाइन किसी भी छोटे बदलाव को बड़े रूप में बदल सकता है।)


1

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

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

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

सॉफ्टवेयर में सभी काम स्वाभाविक रूप से बग-स्पॉनिंग है। फुटबॉल खिलाड़ियों को चोटें आती हैं। संगीतकारों को उनके साधन के आधार पर कॉलस या होंठ ऐंठन होती है। (यदि आपको गिटार बजाते समय होंठों में ऐंठन होती है, तो आप इसे गलत कर रहे हैं।) सॉफ्टवेयर डेवलपर्स को बग मिलते हैं। हम उनके स्पॉन रेट को कम करने के तरीके ढूंढना पसंद करते हैं, लेकिन यह कभी भी शून्य नहीं होगा।


3
प्रारंभिक स्थिति भी नकारात्मक हो सकती है। लिगेसी की शक्ति को कम मत समझो :)
मैग्लोब

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

1

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

आपके उदाहरण में, उचित डिज़ाइन ने आपके काम को पहले से आसान बना दिया है: कोड आधार के 20000 या 200000 लाइनों के बजाय, कोड आधार के 2000 लाइनों में बदलाव करना।

उचित डिजाइन व्यापक परिवर्तनों को कम करता है, लेकिन उन्हें समाप्त नहीं करता है।

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


स्वचालन के सुझाव के लिए +1। मुझे लगता है कि मैं वास्तव में अपने बहुत से पुस्तकालय कार्यों के लिए उपयोग करूंगा जो क्लोजर कहते हैं - यह पता लगाने का एक सरल मामला है कि कौन से फ़ंक्शन ब्लॉक लेते हैं और मान को पास करने के लिए तर्क नाम के लिए एक अतिरिक्त प्रतीक पैरामीटर है।
मौजूद है-
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.