प्रक्रियात्मक प्रोग्रामिंग की समस्याएं ओओपी व्यवहार में क्या हल करती हैं?


17

मैंने "C ++ डीमिस्टीफाइड" पुस्तक का अध्ययन किया है । अब मैंने रॉबर्ट लॉफ्र द्वारा "ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग इन टर्बो सी ++ फर्स्ट एडिशन (पहला संस्करण)" पढ़ना शुरू कर दिया है । मुझे प्रोग्रामिंग का कोई ज्ञान नहीं है जो इन पुस्तकों से परे है। यह पुस्तक पुरानी हो सकती है क्योंकि यह 20 साल पुरानी है। मेरे पास नवीनतम संस्करण है, मैं पुराने का उपयोग कर रहा हूं क्योंकि मुझे यह पसंद है, मुख्य रूप से मैं केवल LaOP की पुस्तक के पहले संस्करण के माध्यम से C ++ में प्रयुक्त OOP की बुनियादी अवधारणाओं का अध्ययन कर रहा हूं।

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

ईमानदारी से कहूं तो मैं अपना प्रश्न पोस्ट कर रहा हूं क्योंकि मैं इस पुस्तक में दिए गए स्पष्टीकरण को नहीं टाल रहा हूं: C ++ (4 वें संस्करण) में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग मैं लाओस की पुस्तक में लिखे गए इन कथनों को नहीं कर रहा हूं:

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

मैंने जेफ केंट की पुस्तक "डिस्मिस्टीफाइड सी ++" का अध्ययन किया है, मुझे यह पुस्तक बहुत पसंद है, इस पुस्तक में ज्यादातर प्रक्रियात्मक प्रोग्रामिंग को समझाया गया है। मुझे समझ में नहीं आता है कि प्रक्रियात्मक (संरचित) प्रोग्रामिंग क्यों कमजोर है!

Lafore की पुस्तक कुछ अच्छे उदाहरणों के साथ अवधारणा को बहुत अच्छी तरह से समझाती है। इसके अलावा मैंने Lafore की पुस्तक को पढ़कर एक अंतर्ज्ञान को समझा है कि OOP प्रक्रियात्मक प्रोग्रामिंग से बेहतर है, लेकिन मैं यह जानने के लिए उत्सुक हूं कि वास्तव में प्रक्रियात्मक प्रोग्रामिंग OOP से कमजोर कैसे है।

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

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

तो ये रहा मेरा प्रश्न:

प्रक्रियात्मक प्रोग्रामिंग की कौन सी सीमाएं ओओपी पते को संबोधित करती हैं और यह प्रभावी रूप से व्यवहार में इन सीमाओं को कैसे हटाती है?

विशेष रूप से, ऐसे कार्यक्रमों के लिए उदाहरण हैं जो प्रक्रियात्मक प्रतिमान का उपयोग करके डिजाइन करना मुश्किल है लेकिन आसानी से ओओपी का उपयोग करके डिजाइन किया गया है?

PS: क्रॉस से पोस्ट किया गया: /programming//q/22510004/3429430


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

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

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

1
"कोई फर्क नहीं पड़ता कि कितनी अच्छी तरह से संरचित प्रोग्रामिंग दृष्टिकोण लागू किया जाता है, बड़े कार्यक्रम अत्यधिक जटिल हो जाते हैं ..." यह ओओपी के बहुत अधिक सच है, लेकिन यह मूल रूप से डेवलपर्स द्वारा निर्धारित तरीके से लागू किए जाने पर जटिलता को बेहतर ढंग से प्रबंधित करता है ... और करता है यह काफी हद तक बेहतर / शार्प स्कोप सीमाओं / प्रतिबंधों के माध्यम से होता है यानी एक तरह का कंपार्टमेंटलाइजेशन सिस्टम ... उर्फ ​​एपीआईई: एब्सट्रैक्शन, पॉलिमॉर्फिज्म, इनहेरिटेंस,
एनकैप्सुलेशन

जवाबों:


9

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

घोषणा प्रकार सबसे स्पष्ट प्रतिबंधात्मक प्रतिबंध है (यानी: "साबित करें कि एक्स एक फ्लोट है")। उस डेटा के लिए डिज़ाइन किए जाने वाले फ़ंक्शन से गुजरने के लिए डेटा म्यूटेशन के लिए मजबूर करना एक और है। प्रोटोकॉल प्रवर्तन (विधि आह्वान आदेश) एक और आंशिक रूप से समर्थित प्रतिबंध है: "कंस्ट्रक्टर -> othermethods * -> विध्वंसक"।

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

प्रकार X1 x का उपप्रकार है, t1 t का उपप्रकार है

यह एक प्रक्रियात्मक भाषा में डेटा को एनकैप्सुलेट करने का एक तरीका है जिसमें एफ और जी के तरीकों के साथ एक टाइप टी और इसी तरह एक उपवर्ग t1 है:

t_f (t, x, y, z, ...), t_g (t, x, y, ...) t1_f (t1, x, y, z, ...)

इस कोड का उपयोग करने के लिए जैसा कि है, आपको एक प्रकार की जाँच करनी होगी और जिस प्रकार की f को लागू करना होगा, उसे तय करने से पहले t के प्रकार पर स्विच करना होगा। आप इसके चारों ओर इस तरह काम कर सकते हैं:

टाइप t {d: data f: function g: function}

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

लेकिन डेटा एनकैप्सुलेशन मान्यता है कि उत्परिवर्तनीय स्थिति खराब है। ऑब्जेक्ट ओरिएंटेड सॉल्यूशन इसे तरीकों के पीछे छिपाना है। आदर्श रूप में, किसी वस्तु के सभी तरीकों में एक अच्छी तरह से परिभाषित कॉलिंग ऑर्डर होगा (यानी: कंस्ट्रक्टर -> खुला -> [पढ़ें | लिखना] -> करीब -> विनाश); जिसे कभी-कभी 'प्रोटोकॉल' (शोध: "Microsoft विलक्षणता") कहा जाता है। लेकिन निर्माण और विनाश से परे, ये आवश्यकताएं आमतौर पर टाइप सिस्टम का हिस्सा नहीं हैं - या अच्छी तरह से प्रलेखित। इस अर्थ में, ऑब्जेक्ट राज्य मशीनों के समवर्ती उदाहरण हैं जो विधि कॉल से संक्रमित होते हैं; ऐसा हो सकता है कि आपके पास कई उदाहरण हों और उनका उपयोग अनियंत्रित रूप से इंटरलेस्ड तरीके से किया जा सके।

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

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

समानतावाद के साथ संयोजन में अप्रतिबंधित वस्तु अभिविन्यास लॉकिंग के कारण एक समस्या है। सॉफ्टवेयर ट्रांजैक्शनल मेमोरी (यानी: डेटाबेस में समान मेमोरी ऑब्जेक्ट पर एसीआईडी ​​लेन-देन) से एक तकनीक है "संचार (अपरिवर्तनीय डेटा)" (कार्यात्मक प्रोग्रामिंग हाइब्रिड) दृष्टिकोण द्वारा साझा मेमोरी का उपयोग करने के लिए।

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


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

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

8

प्रक्रियात्मक / कार्यात्मक प्रोग्रामिंग किसी भी तरह से ओओपी से कमजोर नहीं है , यहां तक ​​कि ट्यूरिंग तर्कों में जाने के बिना (मेरी भाषा में ट्यूरिंग पावर है और कुछ भी कर सकता है), जिसका ज्यादा मतलब नहीं है। दरअसल, ऑब्जेक्ट ओरिएंटेड तकनीकों का प्रयोग पहली बार उन भाषाओं में किया गया था, जिनमें उनका बिल्ट-इन नहीं था। इस अर्थ में OO प्रोग्रामिंग प्रक्रियात्मक प्रोग्रामिंग की एक विशिष्ट शैली है । लेकिन यह विशिष्ट विषयों को लागू करने में मदद करता है, जैसे कि मॉड्यूलरिटी, अमूर्तता और जानकारी छिपाना जो कार्यक्रम की समझ और रखरखाव के लिए आवश्यक हैं।

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

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

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

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

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

उदाहरण: ऑब्जेक्ट ओरिएंटेशन को फिर से बनाना

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

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

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

मान लीजिए कि मैं वेक्टर नामक एक वर्ग बनाना चाहता हूं, जिसमें 2-आयामी वैक्टर का प्रतिनिधित्व किया गया है, जिसमें शामिल हैं: वेक्टर जोड़, वेक्टर आकार और समानता।

function vectorrec () {  
  function createrec(x,y) { return [x,y] }  
  function xcoordrec(v) { return v[0] }  
  function ycoordrec(v) { return v[1] }  
  function plusrec (u,v) { return [u[0]+v[0], u[1]+v[1]] }  
  function sizerec(v) { return sqrt(v[0]*v[0]+v[1]*v[1]) }  
  function parallelrec(u,v) { return u[0]*v[1]==u[1]*v[0]] }  
  return [createrec, xcoordrec, ycoordrec, plusrec, sizerec, parallelrec]  
  }  

फिर मैं उपयोग किए जाने वाले वास्तविक फ़ंक्शन नामों के लिए बनाए गए वेक्टर को असाइन कर सकता हूं।

[वेक्टर, xcoord, ycoord, vplus, vsize, vparallel] = वेक्टरक्लास ()

इतना जटिल क्यों हो? क्योंकि मैं फ़ंक्शन वेक्टरक्रैक मध्यस्थ निर्माणों में परिभाषित कर सकता हूं कि मैं बाकी कार्यक्रम के लिए दृश्यमान नहीं होना चाहता हूं, ताकि प्रतिरूपकता को संरक्षित किया जा सके।

हम ध्रुवीय निर्देशांक में एक और संग्रह कर सकते हैं

function vectorpol () {  
  ...  
  function pluspol (u,v) { ... }  
  function sizepol (v) { return v[0] }  
  ...  
  return [createpol, xcoordpol, ycoordpol, pluspol, sizepol, parallelpol]  
  }  

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

function vector () {  
    ...  
    function plusrec (u,v) { ... }  
    ...  
    function pluspol (u,v) { ... }  
    ...  
    function plus (u,v) { if u[2]='rec' and v[2]='rec'  
                            then return plusrec (u,v) ... }  

    return [ ..., plus, ...]  
    }

मैंने क्या प्राप्त किया है: विशिष्ट कार्य अदृश्य रहते हैं (स्थानीय पहचानकर्ताओं की वजह से स्कूपिंग), और बाकी कार्यक्रम केवल वेक्टरक्लास को कॉल द्वारा लौटाए गए सबसे सार का उपयोग कर सकते हैं।

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

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

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

मैं एक वस्तु उन्मुख सुविधा के इस पुनर्निर्माण में, यहां रुकूंगा।

मैंने जो करने की कोशिश की, वह यह दर्शाता है कि विरासत और अन्य ऐसी विशेषताओं सहित पर्याप्त रूप से शक्तिशाली भाषा में प्रयोग करने योग्य वस्तु अभिविन्यास का निर्माण करना बहुत कठिन नहीं है। दुभाषिया की मेटाकार्युलरिटी मदद कर सकती है, लेकिन ज्यादातर सिंटैक्टिक स्तर पर, जो अभी भी नगण्य से दूर है।

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

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

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

मेरा मानना ​​है कि यह समझने के लिए एक अच्छी किताब एबेल्सन एंड सुस्मान हो सकती है : कंप्यूटर प्रोग्राम की संरचना और व्याख्या


8

थोड़ा इतिहास क्रम में है, मुझे लगता है।

1960 के दशक के मध्य से 1970 के मध्य तक के युग को आज "सॉफ्टवेयर संकट" के रूप में जाना जाता है। मैं 1972 के अपने ट्यूरिंग अवार्ड व्याख्यान में दिज्क्स्त्र से बेहतर नहीं लगा सकता:

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

यह पहले 32-बिट कंप्यूटर, पहले सच्चे मल्टीप्रोसेसर और पहले एम्बेडेड कंप्यूटर का समय था, और शोधकर्ताओं के लिए यह स्पष्ट था कि ये भविष्य में प्रोग्रामिंग के लिए महत्वपूर्ण होने जा रहे थे। यह इतिहास में एक समय था जब ग्राहक पहली बार प्रोग्रामर की क्षमता से बाहर हो गए थे।

अप्रत्याशित रूप से, यह प्रोग्रामिंग अनुसंधान में उल्लेखनीय रूप से उपजाऊ समय था। 1960 के दशक के मध्य से पहले, हमारे पास एलआईएसपी और एपी / एल था, लेकिन "मुख्य" भाषाएं मौलिक रूप से प्रक्रियात्मक थीं: फोरट्रान, अल्गोल, कॉबोल, पीएल / आई और इसी तरह। 1960 के दशक के मध्य से 1970 के दशक के मध्य तक, हमें लोगो, पास्कल, सी, फोर्थ, स्मॉलटाक, प्रोलॉग, एमएल और मोडुला मिला, और यह SQL और उसके पूर्ववर्तियों की तरह डीएसएल की गिनती नहीं कर रहा है।

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

यह वह संदर्भ है जिसमें OOP के बारे में आया था। 1970 के दशक के आरंभिक प्रश्न आपके प्रश्न का उत्तर देते हैं कि OOP अभ्यास में क्या समस्याएँ हल करता है, पहला उत्तर यह है कि यह इतिहास की उस अवधि में प्रोग्रामर का सामना कर रहे कई समस्याओं (समकालीन और प्रत्याशित दोनों) को हल करने के लिए प्रकट हुआ था। हालांकि, यह वह समय नहीं है जब OO मुख्यधारा बना। हम जल्द ही मिल जाएगा।

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

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

एक बात जो आप नोट कर सकते हैं, वह गायब है, और यह विरासत है, और इसके लिए एक कारण है।

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

दूसरी ओर, विरासत, एक ठोस प्रोग्रामिंग भाषा सुविधा है। OOP सिस्टम को लागू करने के लिए वंशानुक्रम उपयोगी हो सकता है। या कम से कम, 1990 के दशक की शुरुआत तक यही स्थिति थी।

1980 के दशक के मध्य से 1990 के मध्य तक का समय भी इतिहास में एक समय था जब चीजें बदल रही थीं। इस समय के दौरान, हमारे पास सस्ते, सर्वव्यापी 32-बिट कंप्यूटर का उदय था, इसलिए व्यवसायों और कई घरों में एक कंप्यूटर लगाने का खर्च हो सकता है जो हर डेस्क पर दिन के सबसे निचले-छोर मेनफ्रेम के रूप में लगभग शक्तिशाली था। यह आधुनिक जीयूआई, और नेटवर्क ऑपरेटिंग सिस्टम के उदय का युग भी था।

यह इस संदर्भ में था कि ऑब्जेक्ट ओरिएंटेड एनालिसिस एंड डिज़ाइन का उदय हुआ।

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

तो आपके प्रश्न का 1990 का उत्तर यह है कि यह डोमेन-उन्मुख विश्लेषण और डिजाइन पद्धति के लिए सबसे अच्छा (उस समय) समाधान का समर्थन करता है।

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

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

तो आधुनिक उत्तर है: यह आधुनिक दुनिया के लिए इंटरफेसिंग की समस्या को हल करता है। आधुनिक दुनिया OOP पर उसी कारण से बनाई गई है कि 1880 की दुनिया भाप पर बनी थी: हम इसे समझते हैं, हम इसे नियंत्रित कर सकते हैं, और यह काम काफी अच्छी तरह से करता है।

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


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

1
ऑपरेटिंग सिस्टम के आंतरिक संगठन (ओनिक्स में "डिवाइस वर्ग" का विचार अनिवार्य रूप से एक ऐसा वर्ग है जिसमें से ड्राइवर विरासत में आते हैं) ओम ने सबसे पहले सिमूला -67 (सिमुलेशन) में दिखाया । Parnas ' "मापदंड मॉड्यूल में सड़ते हुए प्रणालियों में इस्तेमाल किया जा करने के लिए पर" , CACM 15:12 (1972), पीपी। 1052-1058 में Wirth के Modula सत्तर के दशक से भाषा, "सार डेटा प्रकार" एक ही रास्ता या में सभी पूर्ववर्ती हैं अन्य।
वॉनब्रांड

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

6

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

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

कहते हैं कि मैं अजगर में एक कार्ड गेम लिखना चाहता हूं। मैं कार्डों का प्रतिनिधित्व कैसे करूंगा?

अगर मुझे OOP के बारे में पता नहीं था, तो मैं इसे इस तरह से कर सकता हूं:

cards=["1S","2S","3S","4S","5S","6S","7S","8S","9S","10S","JS","QS","KS","1H","2H",...,"10C","JC","QC","KC"]

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

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

अब अगर मैं यह पता लगाना चाहता हूं कि मैं किस कार्ड को खिलाड़ी को प्रदर्शित करने के उद्देश्य से काम कर रहा हूं, तो मुझे इस तरह के कार्य की आवश्यकता होगी:

def card_code_to_name(code):
    suit=code[1]

    if suit=="S":
        suit="Spades"
    elif suit=="H"
        suit="Hearts"
    elif suit=="D"
        suit="Diamonds"
    elif suit=="C"
        suit="Clubs"

    value=code[0]

    if value=="J":
        value="Jack"
    elif value="Q":
        value="Queen"
    elif value="K"
        value="King"

    return value+" of "+suit

थोड़ा बड़ा, लंबा, और अकुशल, लेकिन यह काम करता है (और बहुत ही असाध्य है, लेकिन यहां बिंदु के बगल में है)।

अब क्या होगा अगर मैं चाहता हूं कि कार्ड स्क्रीन के चारों ओर घूम सकें? मुझे किसी तरह उनका पद संचय करना होगा। मैं इसे उनके कार्ड कोड के अंत में जोड़ सकता हूं, लेकिन यह थोड़ा अनिष्टकारी हो सकता है। इसके बजाय, आइए एक और सूची बनाएं कि प्रत्येक कार्ड कहां है:

cardpositions=( (1,1), (2,1), (3,1) ...)

फिर मैं अपना कोड लिखता हूं ताकि सूची में प्रत्येक कार्ड की स्थिति का सूचकांक कार्ड के सूचकांक के समान हो।

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

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

अब इसे OOP तरीका आज़माते हैं।

कोड की एक सूची के बजाय, आइए एक कार्ड वर्ग को परिभाषित करें और उसमें से कार्ड ऑब्जेक्ट की एक सूची बनाएं।

class Card:

    def __init__(self,value,suit,pos,sprite,flipped=False):
        self.value=value
        self.suit=suit
        self.pos=pos
        self.sprite=sprite
        self.flipped=flipped

    def __str__(self):
        return self.value+" of "+self.suit

    def flip(self):
        if self.flipped:
            self.flipped=False
            self.sprite=load_card_sprite(value, suit)
        else:
            self.flipped=True
            self.sprite=load_card_back_sprite()

deck=[]
for suit in ("Spades","Hearts","Diamonds","Clubs"):
    for value in ("1","2","3","4","5","6","7","8","9","10","Jack","Queen","King"):
        sprite=load_card_sprite(value, suit)
        thecard=Card(value,suit,(0,0),sprite)
        deck.append(thecard)

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

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

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


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

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

क्या कोई गैर-ओओपी भाषाएँ हैं जो किसी फ़ंक्शन को किसी सूचक को एक फ़ंक्शन के साथ-साथ एक फ़ंक्शन के लिए एक पॉइंटर लेने की अनुमति देती हैं, जिसका पहला पैरामीटर उसी तरह की चीज़ के लिए एक पॉइंटर है, और कंपाइलर को मान्य है कि फ़ंक्शन उपयुक्त है पारित सूचक के लिए?
सुपरकैट

3

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

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

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

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

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

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


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

2
@DavidRicherby हमारे पास प्रक्रियात्मक पुस्तकालय था, लेकिन हमने जो पदावनत किया, वह सभी जगह कोड होने के बारे में नहीं था। मुद्दा यह था कि हमने यह पीछे किया। कोई भी कुछ भी करने की कोशिश नहीं कर रहा था, यह स्वाभाविक रूप से हुआ।
पहर

@DavidRicherby क्या आप प्रक्रियात्मक पुस्तकालय कार्यान्वयन का कोई उदाहरण दे सकते हैं ताकि मैं यह सुनिश्चित कर सकूं कि हम उसी चीज के बारे में बात कर रहे हैं?
पहर

2
आपके उत्तर के लिए धन्यवाद और +1। कुछ समय पहले एक अन्य अनुभवी प्रोग्रामर ने साझा किया कि कैसे OOP ने अपनी परियोजना को और अधिक विश्वसनीय मंचों से बनाया है ।devshed.com / programming-42 / मुझे लगता है कि OOP को बहुत ही समझदारी से कुछ पेशेवरों द्वारा डिजाइन किया गया था, जिन्हें प्रक्रियात्मक दृष्टिकोण में कुछ समस्याओं का सामना करना पड़ा हो सकता है।
user31782 8

2

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

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

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

यह पत्र प्रायोगिक / मात्रात्मक / वैज्ञानिक विश्लेषण को नियोजित करता है और विशेष रूप से समर्थन करता है कि नौसिखिया प्रोग्रामर द्वारा समझ को कुछ मामलों में OOP कोडिंग विधियों के साथ सुधार किया जाता है, लेकिन अन्य मामलों में (प्रोग्राम आकार के सापेक्ष) अनिर्णायक था । ध्यान दें कि यह OOP श्रेष्ठता के बारे में अन्य उत्तरों में और OOP अधिवक्ताओं द्वारा उन्नत होने के कई / प्रमुख दावों में से एक है। अध्ययन संभवतः एक मनोवैज्ञानिक तत्व को माप रहा था जिसे "संज्ञानात्मक भार / उपरि" के रूप में जाना जाता है ।

  • कंप्यूटर के साथ बातचीत नौसिखिया प्रोग्रामर द्वारा वस्तु उन्मुख और प्रक्रियात्मक कार्यक्रमों की समझ की तुलना । सुसान विडेनबेक, वेनिला रामलिंगम, सुसिला सरसम्मा, सिंथिया एल कॉरिटोर (1999)

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

यह सभी देखें:


1
मेरे पास प्रायोगिक अध्ययन के लिए सम्मान है। हालांकि, यह पता लगाने का मुद्दा है कि वे सही प्रश्नों को संबोधित करते हैं। ओओपी कहा जा सकता है, और इसका उपयोग करने के तरीकों में बहुत सारे चर हैं, एकल अध्ययन के लिए सार्थक, इम्हो। प्रोग्रामिंग में कई चीजों की तरह, OOP को विशेषज्ञों ने अपनी जरूरतों को पूरा करने के लिए बनाया था । ओओपी की उपयोगिता पर चर्चा करते समय (जो मैंने ओपी के विषय के रूप में नहीं लिया, जो कि यह प्रक्रियात्मक प्रोग्रामिंग की कमी को संबोधित करता है), एक पूछ सकता है: क्या सुविधा, किसके लिए, किस उद्देश्य के लिए? तभी क्षेत्र अध्ययन पूरी तरह से सार्थक हो जाता है।
बबौ

1
उपाख्यान चेतावनी: यदि कोई समस्या छोटी है (जैसे कि कोड की लगभग 500-1000 पंक्तियाँ), तो OOP को मेरे अनुभव में कोई फर्क नहीं पड़ता है, यह उस सामान के बारे में चिंता करने से भी हो सकता है जो बहुत कम अंतर करता है। यदि समस्या बड़ी है, और "विनिमेय टुकड़े" का कुछ रूप है, जिसे बाद में जोड़ना संभव हो सकता है (एक जीयूआई में विंडोज़, एक ऑपरेटिंग सिस्टम में डिवाइस, ...) संगठन ओओपी अनुशासन प्रदान करता है जो अपरिहार्य है। आप निश्चित रूप से ओओपी को भाषा समर्थन के बिना प्रोग्राम कर सकते हैं (उदाहरण के लिए लिनक्स कर्नेल देखें)।
वॉनब्रांड

1

सावधान रहे। आर। किंग "माई कैट इज ऑब्जेक्ट-ओरिएंटेड" द्वारा क्लासिक को "ऑब्जेक्ट-ओरिएंटेड कॉन्सेप्ट्स, डेटाबेस और एप्लिकेशन" (किम और लोचोव्स्की, एड्स) (एसीएम, 1989) में पढ़ें। "ऑब्जेक्ट ओरिएंटेड" क्लियरकट कॉन्सेप्ट से ज्यादा बज़-वर्ड बन गया है।

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


0

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग को संक्षिप्त करने के लिए प्रक्रियात्मक प्रोग्रामिंग में मौजूद डेटा सुरक्षा मुद्दों को संबोधित करता है। यह डेटा को इनकैप्सुलेट करने की अवधारणा का उपयोग करके किया जाता है, जिससे केवल वैध वर्गों को डेटा प्राप्त करने की अनुमति मिलती है। पहुँच संशोधक इस लक्ष्य को प्राप्त करने की सुविधा प्रदान करते हैं। उम्मीद है की वो मदद करदे।:)


प्रक्रियात्मक प्रोग्रामिंग में मौजूद डेटा सुरक्षा मुद्दे क्या हैं?
user31782

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

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

यदि आप इसे विश्व स्तर पर घोषित नहीं करते हैं तो यह वैश्विक परिवर्तनशील नहीं है।
मनु

1
"सुरक्षित" या "सही" एक विनिर्देश के बिना कुछ भी मतलब नहीं है। ये चीजें उस लक्ष्य के लिए कोड पर एक विनिर्देश लगाने का प्रयास कर रही हैं: प्रकार, वर्ग परिभाषाएं, डिज़ाइनबायोक्रेक्ट, आदि। आपको "सुरक्षा" इस अर्थ में मिलती है कि आप निजी डेटा सीमाओं को अदृश्य बना सकते हैं; यह मानते हुए कि आपको निष्पादित करने के लिए वर्चुअल मशीन अनुदेश सेट का पालन करना चाहिए। ऑब्जेक्ट ओरिएंटेशन आंतरिक मेमोरी को किसी ऐसे व्यक्ति से नहीं छिपाएगा जो सीधे मेमोरी पढ़ सकता है, और एक खराब ऑब्जेक्ट प्रोटोकॉल डिज़ाइन डिजाइन द्वारा रहस्यों को सौंप रहा है।
रॉब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.