प्रक्रियात्मक / कार्यात्मक प्रोग्रामिंग किसी भी तरह से ओओपी से कमजोर नहीं है , यहां तक कि ट्यूरिंग तर्कों में जाने के बिना (मेरी भाषा में ट्यूरिंग पावर है और कुछ भी कर सकता है), जिसका ज्यादा मतलब नहीं है। दरअसल, ऑब्जेक्ट ओरिएंटेड तकनीकों का प्रयोग पहली बार उन भाषाओं में किया गया था, जिनमें उनका बिल्ट-इन नहीं था। इस अर्थ में 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 अन्य भाषाओं की सीमाओं को संबोधित नहीं करता है, लेकिन यह प्रोग्रामिंग कार्यप्रणालियों का समर्थन करता है या लागू करता है, जो बेहतर कार्यक्रम लिखने में मदद करता है, इस प्रकार कम अनुभवी उपयोगकर्ताओं को अच्छी प्रथाओं का पालन करने में मदद करता है जो कि अधिक उन्नत प्रोग्रामर उस समर्थन के बिना उपयोग और विकास कर रहे हैं।
मेरा मानना है कि यह समझने के लिए एक अच्छी किताब एबेल्सन एंड सुस्मान हो सकती है : कंप्यूटर प्रोग्राम की संरचना और व्याख्या ।