पहलू ओरिएंटेड प्रोग्रामिंग बनाम ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग


199

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

मैंने इस AOP प्रतिमान और I am की कुंजियों को एक ही स्थान पर जानने की कोशिश में बहुत सारी जानकारी पढ़ी है, इसलिए, मैं वास्तविक विश्व अनुप्रयोग विकास में इसके लाभों को बेहतर ढंग से समझना चाहता था।

क्या किसी के पास इसका जवाब है?


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

जवाबों:


323

क्यों "बनाम"? यह "बनाम" नहीं है। आप कार्यात्मक प्रोग्रामिंग के साथ संयोजन में पहलू ओरिएंटेड प्रोग्रामिंग का उपयोग कर सकते हैं, लेकिन ऑब्जेक्ट ओरिएंटेड के साथ संयोजन में भी। यह "बनाम" नहीं है, यह " ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के साथ एस्पेक्ट ओरिएंटेड प्रोग्रामिंग" है।

मेरे लिए AOP कुछ "मेटा-प्रोग्रामिंग" है। सब कुछ जो AOP करता है वह इसके बिना भी किया जा सकता है बस अधिक कोड जोड़कर। AOP आपको यह कोड लिखने से बचाता है।

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

void set...(...) {
    :
    :
    Display.update();
}

यदि आपके पास 3 सेट-विधियाँ हैं, तो यह कोई समस्या नहीं है। यदि आपके पास 200 (काल्पनिक) हैं, तो इसे हर जगह जोड़ने के लिए वास्तविक दर्दनाक हो रहा है। जब भी आप एक नया सेट-मेथड जोड़ते हैं, तो आपको इसे अंत तक जोड़ना न भूलें, अन्यथा आपने सिर्फ एक बग बनाया है।

AOP इसे बिना टन के कोड को जोड़कर हल करता है, इसके बजाय आप एक पहलू जोड़ते हैं:

after() : set() {
   Display.update();
}

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

pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);

इसका क्या मतलब है? इसका मतलब है कि अगर किसी विधि को "सेट *" नाम दिया गया है (* इसका मतलब सेट के बाद कोई भी नाम हो सकता है), इस बात की परवाह किए बिना कि विधि कैसे लौटती है (पहला तारांकन) या यह कौन सा पैरामीटर लेता है (तीसरा तारांकन) और यह MyGraphicsClass का एक तरीका है और यह क्लास पैकेज "com.company। *" का हिस्सा है, तो यह एक सेट () पॉइंटकट है। और हमारा पहला कोड कहता है " किसी भी विधि को चलाने के बाद जो एक निर्धारित बिंदु है, निम्न कोड को चलाएं"।

देखें कि कैसे AOP यहाँ समस्या को हल करता है? वास्तव में यहाँ वर्णित सब कुछ संकलन समय पर किया जा सकता है। AOP प्रीप्रोसेसर अपने स्रोत को संशोधित कर सकता है (जैसे कि प्रत्येक सेट-पॉइंटकट विधि के अंत में Display.update () को जोड़कर) यहां तक ​​कि कक्षा को भी संकलित करने से पहले।

हालाँकि, यह उदाहरण AOP की एक बड़ी गिरावट को भी दर्शाता है। एओपी वास्तव में कुछ ऐसा कर रहा है जो कई प्रोग्रामर " एंटी-पैटर्न " मानते हैं । सटीक पैटर्न को " एक्शन एट ए डिस्टेंस " कहा जाता है ।

दूरी पर कार्रवाई एक एंटी-पैटर्न (एक मान्यता प्राप्त सामान्य त्रुटि) है जिसमें कार्यक्रम के एक हिस्से में व्यवहार कार्यक्रम के दूसरे भाग में संचालन की पहचान करने के लिए मुश्किल या असंभव के आधार पर अलग-अलग होता है।

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

अपडेट करें

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

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

तो मेरे उदाहरण में AOP का एक अच्छा उपयोग हमेशा लॉग इन करना होगा यदि किसी मूल्य को एक सेट विधि के माध्यम से अद्यतन किया गया है। यह एक विरोधी पैटर्न नहीं बनाएगा और शायद ही कभी किसी समस्या का कारण होगा।

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


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

7
@ kizzx2: लॉगिंग पर महान बिंदु, वास्तव में - यह सबसे अच्छा उदाहरण है जो मैंने अब तक एओपी की ताकत को देखा है, एओपी के बारे में बहुत कुछ जाने बिना। साझा करने के लिए धन्यवाद!
ब्लंडर्स

@ मीकी, आपका उदाहरण अत्यधिक सरल है और सामान्य उपयोग के मामले को प्रतिबिंबित नहीं करता है। आपके उदाहरण में, Display.updateकोई तर्क नहीं लेता है। क्या होगा यदि हमें तर्कों में पारित करने की आवश्यकता है (उदाहरण के लिए आमतौर पर एक logफ़ंक्शन को messageपैरामीटर की आवश्यकता होगी )? तो क्या हमें AOP के तरीके से ऐसा करने के लिए बॉयलरप्लेट कोड की एक जोड़ी में जोड़ने की आवश्यकता नहीं होगी?
पचेरियर

3
@Pacerier मेरा उदाहरण सरल है क्योंकि SO कोई शिक्षण मंच नहीं है। मैं सिर्फ प्रश्नकर्ता के सवाल का जवाब दे रहा था, शायद जितना आवश्यक था उससे कहीं अधिक विस्तृत। यदि आप एओपी के बारे में अधिक जानना चाहते हैं, तो कुछ प्रोग्रामर प्रलेखन पढ़ने की कोशिश करें और यदि आपके पास एक विस्तृत प्रश्न है, तो इसे यहां क्यों नहीं पूछें? नहीं, एक टिप्पणी में नहीं, जाओ और एक नया प्रश्न बनाएं क्योंकि यही सब है। मुझे यकीन है कि कोई उत्तर में आपके संदेह को दूर करने में सक्षम होगा।
मिकी

2
@Pacerier क्षमा करें, लेकिन मैं आपकी बात को देखने में विफल हूं। यहां देखें: stackoverflow.com/a/8843713/15809 यह कोड हर विधि को हर कॉल करता है जिसमें सभी विधि तर्क प्रकार और मान शामिल हैं। आप इसे एक बार लिखते हैं और किसी भी विधि में जोड़ा गया शून्य बॉयलरप्लेट कोड है, यह उत्तर में दिखाया गया कोड है।
मैकी जूल

29

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

आपको AOP को OOP के प्रतिस्थापन के रूप में नहीं देखना चाहिए, एक अच्छे ऐड-ऑन के रूप में, जो आपके कोड को अधिक स्वच्छ, शिथिल-युग्मित और व्यावसायिक तर्क पर केंद्रित करता है। तो AOP लगाने से आपको 2 प्रमुख लाभ होंगे:

  1. प्रत्येक चिंता का तर्क अब एक ही स्थान पर है, क्योंकि कोड बेस पर सभी बिखरे होने का विरोध किया गया है।

  2. कक्षाएं क्लीनर हैं क्योंकि वे केवल अपनी प्राथमिक चिंता (या कोर कार्यक्षमता) के लिए कोड रखते हैं और माध्यमिक चिंताओं को पहलुओं में स्थानांतरित कर दिया गया है।


27

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


10

मुझे लगता है कि इस सवाल का कोई सामान्य जवाब नहीं है, लेकिन एक बात पर ध्यान दिया जाना चाहिए, कि AOP OOP को प्रतिस्थापित नहीं करता है, लेकिन कुछ अपघटन की विशेषताएं जोड़ता है जो प्रमुख संरचना ( 1 ) (या क्रॉसकिटिंग चिंताओं) के तथाकथित अत्याचार को संबोधित करता है ।

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

ग्रेगोर किस्केल्स ने एक बार Google टेक वार्ता में AOP पर एक दिलचस्प परिचयात्मक बात की थी जिसे मैं देखने की सलाह देता हूं: एस्पेक्ट ओरिएंटेड प्रोग्रामिंग: रेडिकल रिसर्च इन मोड्युलैरिटी


8

सबसे पहले AOP OOP का स्थान नहीं लेगा। AOP OOP का विस्तार करता है। ओओपी के विचार और व्यवहार प्रासंगिक बने हुए हैं। एक अच्छा ऑब्जेक्ट डिज़ाइन होने से संभवतः इसे पहलुओं के साथ विस्तारित करना आसान हो जाएगा।

मुझे लगता है कि AOP लाने वाले विचार महत्वपूर्ण हैं। हमें अपने कार्यक्रम में विभिन्न वर्गों पर क्रॉस-कटिंग-चिंताओं को लागू करने के तरीकों को काम करने की आवश्यकता है, ताकि कक्षाओं को खुद को बदलने के बिना। लेकिन मुझे लगता है कि AOP अंततः हमारे द्वारा उपयोग किए जाने वाले अन्य उपकरणों का हिस्सा बन जाएगा, न कि एक अलग उपकरण या तकनीक। हम पहले से ही ऐसा होते हुए देखते हैं।

रूबी और पायथन जैसी कुछ गतिशील भाषाओं में मिश्रण जैसे भाषा निर्माण हैं जो समान समस्याओं को हल करते हैं। यह एओपी की तरह दिखता है, लेकिन भाषा में बेहतर एकीकृत है।

स्प्रिंग और कैसल और अन्य निर्भरता इंजेक्शन ढांचे के एक जोड़े के पास उन वर्गों के लिए व्यवहार जोड़ने के विकल्प हैं जो वे इंजेक्ट करते हैं। यह रन-वे-वेटिंग का एक तरीका है और मुझे लगता है कि इसमें काफी संभावनाएं हैं।

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


1

AOP इस अवधारणा से निपटने वाला एक नया प्रोग्रामिंग प्रतिमान है। एक पहलू एक सॉफ्टवेयर इकाई है जो एप्लिकेशन के एक विशिष्ट गैर-कार्यात्मक हिस्से को लागू करता है।

मुझे लगता है कि यह लेख पहलू उन्मुख प्रोग्रामिंग के साथ शुरू करने के लिए एक अच्छी जगह है: http://www.jaftalks.com/wp/index.php/introduction-to-aspect-oriented-programming/


1

मुझे इस सवाल का जवाब देने में देर हो रही है, लेकिन इसका एक पसंदीदा विषय है तो मुझे अपना विचार साझा करने दें।

OOP का उपयोग मुख्य रूप से आपके व्यावसायिक तर्क को व्यवस्थित करने के लिए किया जाता है जबकि AOP आपकी गैर-कार्यात्मक चीजों को व्यवस्थित करने में मदद करता है जैसे लेखा परीक्षा, लॉगिंग, लेन-देन प्रबंधन, सुरक्षा आदि।

इस तरह से आप गैर-काल्पनिक तर्क के साथ अपने व्यावसायिक तर्क को कम कर सकते हैं जो कोड क्लीनर बनाता है।

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

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