क्या समाधान यथासंभव सामान्य या जितना संभव हो उतना सामान्य होना चाहिए?


124

कहें कि मेरे पास एक इकाई है जिसमें "प्रकार" विशेषता है। 20+ संभावित प्रकार हो सकते हैं।

अब मुझे ऐसा कुछ लागू करने के लिए कहा गया है जो A-> B से प्रकार बदलने की अनुमति देगा, जो कि केवल उपयोग का मामला है।

तो क्या मुझे कुछ ऐसा लागू करना चाहिए जो कि प्रकार के मनमाने परिवर्तन की अनुमति देता है जब तक कि वे वैध प्रकार के हों? या क्या मुझे केवल आवश्यकता के अनुसार इसे A-> B से बदलने और किसी अन्य प्रकार के परिवर्तन जैसे B-> A या A-> C से अस्वीकार करने की अनुमति देनी चाहिए?

मैं दोनों पक्षों से पेशेवरों और विपक्षों को देख सकता हूं, जहां भविष्य में एक समान आवश्यकता होने पर सामान्य समाधान का मतलब कम काम होगा, लेकिन इसका मतलब यह भी होगा कि गलत होने की अधिक संभावना है (हालांकि हम इस पर 100% नियंत्रण करते हैं। बिंदु)।
एक विशिष्ट समाधान कम त्रुटि प्रवण होता है, लेकिन भविष्य में अधिक काम करने की आवश्यकता होती है यदि इसी तरह की आवश्यकता होती है।

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

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

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


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

2
@ T.Sar इसे उत्तर के रूप में जोड़ते हैं और मैं :-)
क्रिस्टोफ

4
आपके विचार में "सामान्य समाधान" क्या है? इसके अलावा, कृपया स्पष्ट करें कि आपको "केवल उपयोग के मामले" से क्या मतलब है। क्या आपका मतलब है कि केवल A-> B से एक संक्रमण की अनुमति है या केवल उस संक्रमण को निर्दिष्ट किया गया है, और यह किसी अन्य राज्य से किसी अन्य राज्य में संक्रमण करने के लिए एक त्रुटि स्थिति नहीं होगी। डेवलपर के रूप में आपको उपयोग के मामले को स्पष्ट करने के लिए लेखक से पूछना होगा। यदि कोई अन्य संक्रमण की अनुमति नहीं है और आपका कोड इसकी परवाह किए बिना अनुमति देता है कि कॉलर को कौन नियंत्रित करता है, तो आपका कोड आवश्यकताओं को पूरा करने में विफल रहा है।
रिबॉल्डएडवी

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

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

जवाबों:


296

अंगूठे का मेरा नियम:

  1. पहली बार जब आप समस्या का सामना करते हैं, केवल विशिष्ट समस्या को हल करते हैं (यह YAGNI सिद्धांत है)
  2. दूसरी बार जब आप एक ही समस्या में भाग लेते हैं, तो पहले मामले को सामान्य करने पर विचार करें, अगर यह बहुत काम नहीं है
  3. एक बार जब आपके पास तीन विशिष्ट मामले हैं, जहां आप सामान्यीकृत संस्करण का उपयोग करने में सक्षम होंगे, तो आपको वास्तव में सामान्यीकृत संस्करण की योजना बनाना शुरू करना चाहिए - अब तक, आपको समस्या को अच्छी तरह से समझना चाहिए कि वास्तव में इसे सामान्य करने में सक्षम होना चाहिए।

बेशक, यह एक दिशानिर्देश है और एक कठिन-और-तेज़ नियम नहीं है: असली जवाब आपके सर्वोत्तम निर्णय का उपयोग करना है, केस के आधार पर।


1
क्या आप बता सकते हैं कि YAGNI क्या है?
बर्नहार्ड

7
@ बर्नहार्ड आपको इसकी आवश्यकता नहीं है । एक बहुत ही उपयोगी सॉफ्टवेयर डिजाइन सिद्धांत।
अंगवेद

4
"पर thing1, thing2, एक सरणी का उपयोग करने के बारे में सोचें। शायद thing1, thing2, thing3, thing[]इसके बजाय लगभग निश्चित रूप से सरणी का उपयोग करें ।" कई चर या एकल सरणी के बीच निर्णय लेने के लिए अंगूठे का एक समान नियम है।
जोकर_vD

15
# 1 नियम का एक और तरीका: "आप एक चीज़ को सामान्य नहीं कर सकते।"
वेन कॉनराड

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

95

एक विशिष्ट समाधान [...] को भविष्य में और अधिक काम करने की आवश्यकता होती है यदि समान आवश्यकता हो

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

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

जब "दूसरा समान मामला" दिखाई देता है, तो सामान्यीकरण के बारे में सोचना शुरू करने का समय है। तब सही ढंग से सामान्यीकरण करना बहुत आसान होगा , क्योंकि यह दूसरी आवश्यकता आपको एक ऐसा परिदृश्य देती है जहाँ आप सही चीजों को सामान्य बना सकते हैं। जब केवल एक मामले के लिए सामान्यीकरण करने की कोशिश की जा रही है, तो आप अंधेरे में शूटिंग कर रहे हैं। संभावना अधिक होती है कि आप कुछ ऐसी चीजों की अति कर दें, जिन्हें सामान्यीकृत करने की आवश्यकता नहीं है, और अन्य भागों को याद करना चाहिए। और फिर जब एक दूसरा मामला सामने आता है और आपको पता चलता है कि आपने गलत चीजों को सामान्य कर दिया है, तो आपके पास इसे ठीक करने के लिए और भी बहुत सारे काम हैं

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


2
मेरे लिए इस जवाब से ओपी के संदर्भ में कोई मतलब नहीं है। वह कह रहा है कि वह अब सामान्य होने में कम समय बिताएगा, और भविष्य में कम समय बिताएगा, जब तक कि भविष्य में कार्यान्वयन के विशिष्ट होने की आवश्यकता न हो। आप "सामान्यीकरण में अतिरिक्त प्रयास निवेश करने" के खिलाफ बहस कर रहे हैं, जबकि ओपी अतिरिक्त प्रयास का निवेश तभी करेंगे जब वे सामान्यीकरण नहीं करेंगे । (सोचो) .... अजीब: $
एमएसबी

2
@ एलएसबी: मेरे संदर्भ को लिखने के बाद उस संदर्भ को जोड़ा गया था और इससे पहले कि ओपी पहले जो कह रहा था, उसके विपरीत जाता है, खासकर उस हिस्से में जिसका मैंने हवाला दिया था। मेरा संपादन देखें।
डॉक ब्राउन

2
इसके अलावा, सामान्यीकृत समाधान अधिक जटिल होगा, इसलिए जब तक आपको इसे दूसरे मामले के लिए अनुकूलित करना होगा, तब तक इसे फिर से समझने में अधिक समय लगेगा।
आंद्रेकेआर

4
डॉक्टर, एक तरफ, लेकिन कभी भी यह अनुमान नहीं लगाया होगा कि आप एक गैर-देशी वक्ता हैं। आपके उत्तर हमेशा अच्छी तरह से लिखे गए हैं और अच्छी तरह से तर्क दिए गए हैं।
user949300

2
मैं आपके उच्चारण की कल्पना करूँगा जब मैं आपके भविष्य के उत्तर पढ़ रहा हूँ। :-)
user949300

64

TL; DR: यह इस बात पर निर्भर करता है कि आप क्या हल करना चाहते हैं।

मैंने इस बारे में अपने Gramps के साथ एक समान बातचीत की है, जबकि हम बात कर रहे थे कि कैसे C # में Func और Action कमाल के हैं। मेरा ग्रैम्प एक बहुत पुराना टाइमर प्रोग्रामर है, जो कि पूरे कंप्यूटर पर काम करने वाले कंप्यूटरों पर सॉफ्टवेयर चलाने के बाद से सोर्स कोड के आसपास है।

उन्होंने अपने जीवन में कई बार टेक बदले। उन्होंने C, COBOL, पास्कल, BASIC, फोरट्रान, स्मॉलटाक, जावा में कोड लिखे और आखिरकार C # को एक शौक के रूप में शुरू किया। मैंने आईबीएम की साइडकिक के नीले संपादक पर कोड की मेरी पहली पंक्तियों को उकेरते हुए उसकी गोद में बैठकर उसकी गोद में बैठना सीख लिया। जब मैं 20 साल का था, तब तक मैंने पहले से ही बाहर खेलने से ज्यादा समय कोडिंग में बिताया था।

वे मेरी यादों में से एक हैं, इसलिए मुझे माफ करना अगर मैं उन्हें वापस लेने के दौरान बिल्कुल व्यावहारिक नहीं हूं। मैं उन पलों का कुछ ज्यादा ही शौकीन हूं।

उसने मुझसे यही कहा:


"क्या हमें किसी समस्या के सामान्यीकरण के लिए जाना चाहिए, या इसे विशिष्ट दायरे में हल करना चाहिए, क्या आप पूछते हैं? अच्छा, यह एक प्रश्न है।"

ग्रैम्प्स ने अपने चेहरे पर अपने चश्मे की स्थिति को ठीक करते हुए, एक संक्षिप्त क्षण के बारे में सोचने के लिए एक विराम लिया। वह अपने पुराने साउंड सिस्टम पर डीप पर्पल के एलपी को सुनते हुए अपने कंप्यूटर पर मैच -3 गेम खेल रहा था।

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

"... पनीर, दादाजी?"

"कोई फर्क नहीं पड़ता कि आप अपने पसंदीदा के बारे में क्या सोचते हैं, हमेशा कोई ऐसा व्यक्ति होगा जो सोचता है कि यह बदबूदार है"।

मैं एक पल के लिए असमंजस में पड़ गया, लेकिन इससे पहले कि मैं कुछ कह पाता ग्रैम्प चल गया।

"जब आप एक कार का निर्माण कर रहे हैं, तो आप एक हिस्से के लिए सामग्री कैसे उठाते हैं?"

"मैं ... मुझे लगता है कि इसमें शामिल लागतों पर निर्भर करता है और क्या करना चाहिए, मुझे लगता है।"

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

बुजुर्ग प्रोग्रामर थोड़ा लेगो ट्रेन मॉडल के लिए पहुंचे, जिसे जारी रखने से पहले उनकी मेज पर है।

"आप केवल यह उत्तर दे सकते हैं कि यदि आप जानते हैं कि आपको उस ईंट की आवश्यकता क्या है। तो आप कैसे जानेंगे कि विशिष्ट समाधान जेनेरिक से बेहतर है, या इसके विपरीत, यदि आपको यह भी पता नहीं है कि आपको क्या समस्या है? हल करने की कोशिश कर रहे हैं? आप एक विकल्प नहीं देख सकते हैं जिसे आप नहीं समझते हैं। "

".. क्या आप सिर्फ मैट्रिक्स बोली ? "

"क्या?"

"कुछ नहीं, जाओ।"

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

ग्रैम्प्स ने लेगो ट्रेन को उसके स्थान पर वापस रख दिया और अपने मैच -3 गेम में वापस आ गया।

"तो, किसी दिए गए समस्या के लिए एक सामान्य या एक विशिष्ट समाधान चुनने में सक्षम होने के लिए आपको सबसे पहले यह समझने की आवश्यकता है कि समस्या क्या है। अन्यथा आप केवल अनुमान लगा रहे हैं, और अनुमान लगाना प्रबंधकों का काम है, न कि प्रोग्रामर का। लगभग। आईटी में सब कुछ, यह निर्भर करता है। ”


इसलिए यह अब आपके पास है। "निर्भर करता है"। सॉफ्टवेयर डिजाइन के बारे में सोचते समय शायद यह सबसे शक्तिशाली दो-शब्द की अभिव्यक्ति है।


14
मुझे यकीन है कि उस कहानी में कुछ उपयोगी है, लेकिन यह पढ़ने के लिए बहुत दर्दनाक था, खेद है
GoatInTheMachine

28
आपका पहला पोस्ट एक छोटा सा मजेदार किस्सा था - और निश्चित रूप से यह एक विचार की बात है - लेकिन जब तक मैं वास्तव में शैली लिखने वाले किसी व्यक्ति को पसंद नहीं करता हूं, तब तक मुझे इस तरह की लंबी कहानियां मिलती हैं और यह व्यक्तिगत ब्लॉग के बाहर थोड़ा अनुचित है
GoatInMachine

16
@ टी। एस नफरत करने वालों की बात नहीं मानते, आपकी पोस्ट गुरु की उपयोगी सलाह का रत्न है। +1
LLlAMnYP

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

3
शायद यह जवाब पनीर की तरह भी है? ;) लेकिन कृपया, "स्मॉलटॉक" को "स्मॉलटॉक" होना चाहिए, और हां, मैं उस आदमी को क्षमा कर रहा हूं ।
फेड एस।

14

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

यदि नहीं, तो आमतौर पर सरल समाधान के लिए जाना बेहतर होता है और बाद में इसे बढ़ाया जाता है। यह बहुत संभव है कि आपके पास तब और अधिक स्पष्ट तस्वीर हो, जो तब आवश्यक हो।


13

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

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


प्रश्न एक ठोस समस्या के बारे में स्पष्ट है।
रिबॉल्डएडीडी

4
इस ठोस समस्या का समाधान करने के लिए जवाब काफी सामान्य है। और यह प्रश्न पर्याप्त नहीं है कि आपको एक ठोस रसीद दी जाए: जैसा कि आप देख सकते हैं, किसी भी डोमेन विवरण का उल्लेख एक प्रश्न में नहीं किया गया है। यहां तक ​​कि वर्ग के नाम भी निर्दिष्ट नहीं हैं (ए और बी की गिनती नहीं है)।
Zapadlo

7
"क्या स्टैकओवरफ्लो का जवाब यथासंभव सामान्य या यथासंभव विशिष्ट होना चाहिए?"
लिंडन व्हाइट

@ लिंडन वाइट को स्टैकओवरफ्लो प्रश्न जितना संभव हो उतना सामान्य होना चाहिए (बहुत व्यापक!) या जितना संभव हो उतना विशिष्ट (जो भी विफलता कहा जाता है!)। हा।

4

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

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

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

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


"आप उन सभी बगों को याद करते हैं जिन्हें आप कोड नहीं करते हैं।" (बास्केटबॉल पोस्टर से: आप उन सभी शॉट्स को याद करते हैं जो आप नहीं लेते हैं)

3

इस विशिष्ट समस्या का सामान्य उत्तर देना मुश्किल है ;-)

यह जितना अधिक सामान्य होगा, भविष्य के परिवर्तनों के लिए उतना ही अधिक समय मिलेगा। इस कारण से कई खेल कार्यक्रम खेल में पात्रों और वस्तुओं के बहुत विस्तृत लेकिन कठोर प्रकार की प्रणाली के निर्माण के बजाय इकाई घटक पैटर्न का उपयोग करते हैं ।

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

यह हमेशा देखने के लायक है कि क्या कोई प्राकृतिक सामान्यीकरण है जो आपको एक सफलता मिलेगी। हालांकि, अंत में, यह संतुलन का सवाल है, इस प्रयास के बीच कि आप अब खर्च कर सकते हैं और भविष्य में आपको जिस प्रयास की आवश्यकता हो सकती है।


3
  1. हाइब्रिड। यह या तो / या सवाल नहीं है। आप केवल विशिष्ट रूपांतरण को लागू करते समय सामान्य प्रकार के रूपांतरणों के लिए एपीआई को डिजाइन कर सकते हैं। (बस सुनिश्चित करें कि यदि कोई आपके सामान्य एपीआई को असमर्थित रूपांतरण के साथ कहता है, तो यह "नहीं-समर्थित" त्रुटि स्थिति के साथ विफल हो जाता है।)

  2. परिक्षण। A-> B रूपांतरण के लिए, मुझे परीक्षणों में से एक (या छोटी संख्या) लिखना होगा। एक सामान्य x-> y रूपांतरण के लिए, मुझे परीक्षणों की एक पूरी मैट्रिक्स लिखनी पड़ सकती है। यह काफी अधिक काम है, भले ही सभी रूपांतरण एक ही सामान्य कार्यान्वयन साझा करते हैं।

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

  3. युग्मन। ए से बी के एक कनवर्टर को ए और बी के (तंग युग्मन) के बारे में कार्यान्वयन विवरण जानना आवश्यक है। यदि A और B अभी भी विकसित हो रहे हैं, तो इसका मतलब है कि मुझे कनवर्टर (और उसके परीक्षण) का पुनरीक्षण करना पड़ सकता है, जो बेकार है, लेकिन कम से कम यह A और B के लिए सीमित है।

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

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


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

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

3

क्या समाधान यथासंभव सामान्य या जितना संभव हो उतना सामान्य होना चाहिए?

यह एक जवाबदेह सवाल नहीं है।

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

  1. प्रथम-क्रम सन्निकटन: डैनियल प्राइडेन, डॉक ब्राउन, एट अल द्वारा वर्णित तीन के सामान्य YAGNI नियम ।

    यह आम तौर पर उपयोगी अनुमानी है क्योंकि यह संभवतः सबसे अच्छा है जो आप कर सकते हैं जो डोमेन और अन्य चर पर निर्भर नहीं करता है।

    तो, प्रारंभिक अनुमान है: हम सबसे विशिष्ट काम करते हैं।

  2. दूसरा-आदेश सन्निकटन: समाधान डोमेन के आपके विशेषज्ञ ज्ञान के आधार पर , आप कहते हैं

    इस मामले में "सामान्य" समाधान के लिए "विशिष्ट" समाधान की तुलना में कम काम की आवश्यकता होती है

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

    हालाँकि, यदि आपके समाधान डोमेन ज्ञान से संकेत मिलता है कि सबसे आसान समाधान बहुत सारे कीड़े खोले जाने की संभावना है, या पर्याप्त रूप से परीक्षण करने के लिए कठिन है, या किसी अन्य समस्या का कारण है, तो कोड के लिए आसान होना आवश्यक रूप से हमारे बदलने के लिए एक अच्छा पर्याप्त कारण नहीं है मूल विकल्प।

  3. तृतीय-क्रम सन्निकटन: क्या आपकी समस्या डोमेन ज्ञान से पता चलता है कि सबसे आसान समाधान वास्तव में सही है, या क्या आप बहुत सारे बदलावों की अनुमति दे रहे हैं जिन्हें आप अर्थहीन या गलत जानते हैं?

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

  4. चौथा-आदेश सन्निकटन: क्या आपके ग्राहक व्यवहार का ज्ञान है, या यह विशेषता दूसरों से कैसे संबंधित है, या परियोजना प्रबंधन प्राथमिकताएं, या ... कोई अन्य नहीं-कड़ाई से तकनीकी विचार आपके वर्तमान कार्य निर्णय को संशोधित करते हैं?


2

सरल उत्तर के साथ उत्तर देना आसान प्रश्न नहीं है। कई जवाबों ने 3 के नियम के आसपास निर्मित हुरिस्टिक्स दिए हैं, या कुछ इसी तरह के। अंगूठे के ऐसे नियमों से परे कदम रखना मुश्किल है।

वास्तव में आपके प्रश्न का उत्तर देने के लिए, आपको यह विचार करना होगा कि आपकी नौकरी सबसे अधिक संभावना है कि वह ए-बी को बदलने वाली किसी चीज़ को लागू न करे। यदि आप एक ठेकेदार हैं, तो शायद यह आवश्यकता है, लेकिन यदि आप एक कर्मचारी हैं, तो आपको कंपनी के लिए कई छोटे कार्य करने के लिए काम पर रखा गया था। A-> B को बदलना उन कार्यों में से एक है। आपकी कंपनी इस बात की देखभाल करने जा रही है कि भविष्य के परिवर्तनों को कितनी अच्छी तरह से किया जा सकता है, भले ही वह अनुरोध में नहीं बताया गया हो। "TheBestImplementation (tm)" को खोजने के लिए, आपको उस बड़ी तस्वीर को देखना होगा जो आप वास्तव में करने के लिए कह रहे हैं, और फिर ए-> बी को बदलने के लिए आपको दिए गए छोटे अनुरोध की व्याख्या करने के लिए उपयोग करें।

यदि आप कॉलेज से कम स्तर के एंट्री प्रोग्रामर हैं, तो अक्सर आपको वही करने की सलाह दी जाती है जो आपको करने के लिए कहा गया था। यदि आपको 15 साल के अनुभव के साथ एक सॉफ्टवेयर वास्तुकार के रूप में काम पर रखा गया है, तो आमतौर पर बड़ी तस्वीर चीजों के बारे में सोचना उचित है। हर वास्तविक नौकरी कहीं न कहीं "संकीर्ण काम है" और "बड़ी तस्वीर के बारे में सोचते हैं" के बीच कहीं गिरने वाली है। यदि आप लोगों से पर्याप्त बातचीत करते हैं और उनके लिए पर्याप्त काम करते हैं तो आपको लगेगा कि आपकी नौकरी उस स्पेक्ट्रम में कहाँ फिट होती है।

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

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


1

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

एक मायने में, आपको अपने अनुभव पर वापस आना होगा। अगर आपका नहीं है, तो डोमेन में कोई और वरिष्ठ है। आप स्वीकार कर सकते हैं कि स्वीकृति मापदंड क्या है। यदि यह कुछ है तो 'उपयोगकर्ता को "ए" से "बी" टाइप करने में सक्षम होना चाहिए "बनाम" उपयोगकर्ता को टाइप करने के लिए वर्तमान मूल्य से किसी भी वैकल्पिक वैकल्पिक मूल्य में परिवर्तन करने में सक्षम होना चाहिए। "

अक्सर स्वीकृति मानदंड व्याख्या के अधीन होते हैं, लेकिन अच्छा QA कर्मचारी कार्य को उचित मानदंड लिख सकता है, जो आवश्यक व्याख्या को न्यूनतम करता है।

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

यदि सामान्य मामला अधिक कठिन था, तो मैं काम शुरू करने से पहले पूछूंगा, लेकिन आपके मामले में अगर मैं यह अनुमान लगा सकता था कि भविष्य में अन्य 'प्रकार' परिवर्तन अनुरोध आने वाले हैं, तो मुझे इसका लालच होगा: a) सामान्य मामले के लिए पुन: प्रयोज्य कुछ लिखें, और बी) इसे एक सशर्त में लपेटें जो केवल अब के लिए ए -> बी की अनुमति देता है।

स्वचालित परीक्षण में वर्तमान मामले के लिए सत्यापित करने के लिए पर्याप्त आसान है, और यदि अन्य उपयोग के मामले सामने आते हैं, तो बाद में अन्य विकल्पों को खोलने के लिए पर्याप्त आसान है।


1

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

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

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


0

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

सिद्धांत रूप में, हाँ। लेकिन इससे जरूरी जेनेरिक समाधान नहीं निकलते।

सॉफ्टवेयर विकास में दो प्रकार के विषय हैं, जहां तक ​​मेरा संबंध है, जहां आपको भविष्य में होने वाले बदलाव की आशा करनी चाहिए:

  • पुस्तकालयों का उपयोग 3 जी पार्टियों द्वारा किया जाना है, और
  • समग्र सॉफ्टवेयर वास्तुकला।

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

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

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

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

जेनेरिक सॉल्यूशन की तरह लगने वाला रास्ता क्या है?

नहीं, ऐसा लगता है कि आपके पास प्रोग्रामिंग वातावरण, भाषाएं, और टूलींग होनी चाहिए जो आपको जरूरत पड़ने पर रिफ्लेक्टर के लिए आसान और मजेदार बनाती है। सामान्य समाधान प्रदान नहीं करते हैं कि; वे वास्तविक डोमेन से आवेदन को कम कर देते हैं।

आधुनिक ओआरएम या एमवीसी रूपरेखा पर एक नज़र डालें, उदाहरण के लिए रूबी ऑन रेल्स; आवेदन स्तर पर, सभी का ध्यान गैर-सामान्य काम करने पर है। रेल पुस्तकालयों में स्वयं लगभग 100% सामान्य हैं, लेकिन डोमेन कोड (जो कि आपका सवाल है) उस पहलू में न्यूनतम शेंनिगन करना चाहिए।


0

समस्या के बारे में सोचने का एक अलग तरीका यह है कि क्या समझ में आता है।

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

जब प्रबंधन ने अन्य लोगों को एक सुविधा तक पहुंचने की अनुमति देने का फैसला किया, तो हम केवल एक ध्वज को बदलकर ऐसा करने में सक्षम थे।

स्पष्ट रूप से यह विशिष्ट प्रकार का रूपांतरण करने के लिए समझ में आता है। क्या यह भी व्यसनी प्रकार रूपांतरण बनाने के लिए समझ में आता है?

ध्यान रखें, यदि सामान्य समाधान को लागू करने के लिए तेज़ है, तो एपिक मामले भी आसान है, बस जांचें कि यह एकमात्र प्रकार का रूपांतरण है जिसे आप अनुमति दे रहे हैं।

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

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