अमूर्तता: समस्या को सुलझाने और एक सामान्य समाधान के बीच युद्ध [बंद]


33

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

ऐसा करने से आमतौर पर मुझे अपने कोड का पुन: उपयोग करने की अनुमति मिलती है और समस्या के लिए एक अधिक सामान्य समाधान होता है जो (या नहीं) फिर से आ सकता है।

फिर मेरे सिर में यह आवाज कहती है, बस समस्या को हल कर दो! आपके पास जितना समय है उससे अधिक समय क्यों?

हम सभी ने वास्तव में इस सवाल का सामना किया है, जहां एब्सट्रैक्शन आपके दाएं कंधे पर है और बाईं ओर सॉल्व-इट-स्टुपिड बैठता है।

कौन सी और कितनी बार सुनना है? इसके लिए आपकी क्या रणनीति है? क्या आपको सब कुछ अमूर्त कर देना चाहिए?


1
"अमूर्त और सामान्य के रूप में" आम तौर पर प्रोग्रामर के पति के रूप में जाना जाता है :) हालांकि, मर्फी के नियम के कारण, अनुकूलन की एक डिग्री की आवश्यकता होगी जब आप अगले कार्य पर काम करेंगे, वह होगा जो आपने प्रदान नहीं किया है।
Matthieu M.

1
सबसे अच्छे सवालों में से एक!
explorest

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

जवाबों:


27

कौन सी और कितनी बार सुनना है?

कभी भी अमूर्त नहीं होना चाहिए जब तक आप।

जावा में, उदाहरण के लिए, आपको इंटरफेस का उपयोग करना चाहिए। वे एक अमूर्त हैं।

पायथन में आपके पास इंटरफेस नहीं है, आपके पास डक टाइपिंग है, और आपको अमूर्तता के स्तर की आवश्यकता नहीं है। तो तुम बस नहीं।

इसके लिए आपकी क्या रणनीति है?

जब तक आप इसे तीन बार नहीं लिख लेते, तब तक सार न करें।

एक बार - अच्छी तरह से - एक बार। बस इसे हल करें और आगे बढ़ें।

दो बार संकेत है कि यहां एक पैटर्न हो सकता है। या वहाँ नहीं हो सकता है। यह सिर्फ संयोग हो सकता है।

तीन बार एक पैटर्न की शुरुआत है। अब यह संयोग को पार कर जाता है। अब आप सफलतापूर्वक सार कर सकते हैं।

क्या आपको सब कुछ अमूर्त कर देना चाहिए?

नहीं।

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

ऐसा करने से आमतौर पर मैं अपने कोड का पुन: उपयोग कर सकता हूं

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


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

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

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

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

1
@ जैसनबेकर यह किसी के साथ सोने का अनसुना कारण नहीं है। शायद आप "पैसे" के बारे में सोच रहे थे?

19

आह, YAGNI। प्रोग्रामिंग की सबसे गाली वाली अवधारणा।

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

जैसा कि कहा जाता है "सबसे सरल काम करो जो संभवतः काम कर सकता है"। बात यह है कि लोगों को हमेशा भ्रमित है सरल के साथ आसान । सादगी काम लेती है। लेकिन यह प्रयास के लायक है।

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

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


simpleऔर के बीच अच्छा अंतर easy!
Matthieu M.


"लेकिन मेरा अनुभव यह है कि कुछ कंपनियां" - दिलचस्प रूप से, एकेडेमिया में रिवर्स सच हो सकता है।
स्टीव बेनेट

12

एक नपुंसकता:

  1. सामान्यता महंगी है।

  2. आप दूसरे लोगों के पैसे खर्च कर रहे हैं।

  3. इसलिए हितधारकों को सामान्यता का खर्च उचित होना चाहिए।

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

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

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

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

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


2
उपयोगी सिद्धांतों के लिए +1, पैसे के बारे में यह सब बनाने के लिए -1।
मेसन व्हीलर

4
@ मेसन: यह पैसे के बारे में नहीं है , यह प्रयास के बारे में है । धन प्रयास का एक व्यावहारिक उपाय है । दक्षता उत्पादन प्रति प्रयास अर्जित लाभ है; फिर से, धन में लाभ अर्जित लाभ का एक व्यावहारिक उपाय है । प्रयास, लागत और लाभ को मापने के लिए किसी तरह से आने की तुलना में पैसे के अमूर्त पर चर्चा करना आसान है। क्या आप किसी अन्य तरीके से प्रयास, लागत और लाभ को मापना पसंद करेंगे? बेहतर तरीके से प्रस्ताव करने के लिए स्वतंत्र महसूस करें।
एरिक लिपर्ट

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

2
@Orbling: मैं अनावश्यक, महंगे, बेकार प्रयासों का दृढ़ता से विरोध करता हूं जो संसाधनों को योग्य और महत्वपूर्ण परियोजनाओं से दूर ले जाता है। यदि आप यह सुझाव दे रहे हैं कि यह मुझे "आलसी" बनाता है तो मैं प्रस्तुत करता हूं कि आप "आलसी" शब्द का प्रयोग असामान्य तरीके से कर रहे हैं।
एरिक लिपर्ट

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

5

बस स्पष्ट होना, कुछ को सामान्यीकृत करना और अमूर्तता को लागू करना पूरी तरह से दो अलग-अलग चीजें हैं।

उदाहरण के लिए, एक फ़ंक्शन पर विचार करें जो मेमोरी की प्रतिलिपि बनाता है।

फ़ंक्शन एक अमूर्त है जो छुपाता है कि 4 बाइट्स की प्रतिलिपि कैसे बनाई जाती है।

int copy4Bytes (char * pSrc, char * pDest)

एक सामान्यीकरण इस फ़ंक्शन को बाइट्स की किसी भी संख्या की प्रतिलिपि बना रहा होगा।

int copyBytes (char * pSrc, char * pDest, int numBytesToCopy)

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

विशेष रूप से आपके प्रश्न से संबंधित, एब्स्ट्रेक्शन न केवल एक कोड पुन: उपयोग के दृष्टिकोण से उपयोगी है। अक्सर बार अगर सही ढंग से किया जाता है तो यह आपके कोड को अधिक पठनीय और रखरखाव योग्य बना देगा। ऊपर दिए गए उदाहरण का उपयोग करते हुए, यदि आप कोड copyBytes () या लूप के लिए एक बार में डेटा एक इंडेक्स मूविंग डेटा के माध्यम से पुनरावृत्ति कर रहे हैं, तो क्या पढ़ना और समझना आसान है? अमूर्त एक प्रकार का स्व दस्तावेज प्रदान कर सकता है जो मेरी राय में कोड के साथ काम करना आसान बनाता है।

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


अमूर्त और सामान्यीकरण के बीच अंतर बनाने के लिए +1।
जोरिस मे

4

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

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


1
यह रिफलेक्टिंग रूल के मेरे संस्करण जैसा लगता है: स्ट्राइक टू! refactor!
फ्रैंक शियरर

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

+1: मेरा मानना ​​है कि यह द प्रोगैमैटिक प्रोग्रामर में लगभग शब्दशः IIRC पर काफी पहले से ही उल्लेखित है ।
स्टीवन एवर्स

ओह निश्चित रूप से। केवल एक उदाहरण के साथ अमूर्त करने के लिए कुछ भी नहीं है: जैसे ही आपके पास एक दूसरा उदाहरण होता है, आप देख सकते हैं कि क्या आम (साझा) है और क्या नहीं, और आप अमूर्त कर सकते हैं!
फ्रैंक शियरर

दो का एक नमूना मेरी राय में अनंत के लिए सामान्य करने के लिए बहुत छोटा है। दूसरे शब्दों में, बहुत जल्दी।

2

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

पहला: समयपूर्व सामान्यता महंगी है।

दूसरा: अपने मॉडल में केवल उन चीजों का प्रतिनिधित्व करें जो हमेशा समस्या डोमेन में हैं और जिनके वर्ग संबंध अपरिवर्तित हैं।

तीसरा: अपनी नीतियों को अपने तंत्र से दूर रखें।


1

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

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


0

मैं KISS सिद्धांत का एक बड़ा प्रशंसक हूं।

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


पूर्णतावाद के प्रति अरुचि क्यों? (मैंने आपको नीचे वोट नहीं दिया)
परिक्रमा

पूर्णता के लिए लक्ष्य नहीं करना मेरे लिए काम करता है। क्यूं कर? क्योंकि मुझे पता है कि मेरे कार्यक्रम कभी सही नहीं होंगे। पूर्णता की कोई मानक परिभाषा नहीं है, इसलिए मैं बस कुछ ऐसा प्रदान करना चुनता हूं जो अच्छी तरह से काम करता हो।
पाब्लो

-1

जहां एब्स्ट्रेक्शन आपके दाएं कंधे पर है और सॉल्यूशन-इट- स्टुपिड बाईं ओर बैठता है।

मैं "इसे बेवकूफी से हल करने" से सहमत नहीं हूं , मुझे लगता है कि यह अधिक "इसे स्मार्ट को हल करना" हो सकता है ।

क्या होशियार:

  • एक जटिल सामान्यीकृत समाधान लिखना जो कई मामलों का समर्थन कर सकता है
  • संक्षिप्त और संक्षिप्त कोड लिखना जो समस्या को हाथ में हल करता है और बनाए रखना आसान है, और जिसे भविष्य में बढ़ाया जा सकता है, यदि यह आवश्यक है।

डिफ़ॉल्ट विकल्प दूसरा होना चाहिए। जब तक आप जेनरेशनल की आवश्यकता का प्रदर्शन नहीं कर सकते।

सामान्यीकृत समाधान केवल तभी होना चाहिए जब आप जानते हों कि यह एक ऐसी चीज है जिसका उपयोग कई अलग-अलग परियोजनाओं / मामलों में किया जाएगा।

आमतौर पर मुझे लगता है कि सामान्यीकृत समाधान "कोर लाइब्रेरी कोड" के रूप में सबसे अच्छे हैं।


यदि आप यहाँ सभी अनुमान लगा सकते हैं, तो आपको कोई समस्या नहीं होगी। लघु और आसान बनाए रखने के लिए परस्पर अनन्य हैं। यदि आप जानते हैं कि कुछ का पुन: उपयोग किया जाएगा, तो सामान्य समाधान यह कहेगा।
जेफ ओ

@Jeff मैं काफी यकीन नहीं है मैं अपनी टिप्पणी को समझने ..
Darknight

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