क्या कुछ समस्याओं को एओपी के साथ अधिक हल किया जाता है?


19

मैं पहलू ओरिएंटेड प्रोग्रामिंग के विचार पर आया हूं, और मुझे इसके साथ कुछ चिंताएं हैं।

मूल विचार यह प्रतीत होता है कि हम क्रॉस-कटिंग चिंताओं को लेना चाहते हैं जो वस्तु का उपयोग करके अच्छी तरह से संशोधित नहीं हैं और उन्हें संशोधित करते हैं। वह सब बहुत ठीक और अच्छा है।

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

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

क्या AOP एक अच्छा अभ्यास है? क्या कुछ प्रोग्रामिंग समस्याओं को AOP के साथ अधिक सुरुचिपूर्ण ढंग से हल किया गया है?


आह, प्रसिद्ध बंदर पैच!
मुअदिदिब

1
मैंने प्रश्न को उसके स्वर को सुधारने के लिए संपादित किया है, और फिर से खोलने के लिए मतदान किया है।
रॉबर्ट हार्वे

क्वेस्टियो को यहां एक अलग रूप में भी फिर से पूछा गया है: प्रोग्रामर.स्टैकएक्सचेंज
पीटर बॉटन

जवाबों:


19

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

  1. लॉगिंग और मॉनिटरिंग
  2. क्षमता का परिक्षण
  3. डिबगिंग और ट्रेसिंग
  4. कार्यशीलता को पूर्ववत् करें
  5. इनपुट और आउटपुट का सत्यापन
  6. मौजूदा वस्तुओं के व्यवहार को मोड़ना
  7. वस्तु फ़िल्टर
  8. सुरक्षा कार्यान्वयन
  9. लेन-देन का प्रबंध करना

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

यहां मुख्य बिंदु यह है कि AOP व्यवहार को एनकैप्सुलेट करता है जो कि पूरे अनुप्रयोग में 1), और 2) एप्लिकेशन की प्राथमिक कार्यक्षमता के लिए परिधीय है।


7

खेल के अंत में आ रहा है, लेकिन मैं इसे बाद के डेवलपर्स के लिए प्रदान करता हूं जो इस प्रश्न पर ठोकर खा सकते हैं।

यदि आपका आवेदन सही तरीके से संचालित करने के लिए निर्भर करता है, तो मैं AOP के खिलाफ दृढ़ता से सलाह दूंगा । पहलू इस तरह काम करते हैं:

  • सलाह (अतिरिक्त व्यवहार) पर लागू होती है
  • बिंदुओं को मिलाएं (ऐसे स्थान जहां अतिरिक्त कोड संलग्न किया जा सकता है, इस तरह की विधि शुरू या समाप्त होती है, या जब किसी दिए गए इवेंट ट्रिगर होते हैं)
  • ... जहां पॉइंटकट (एक पैटर्न जो पता लगाता है कि क्या दिया गया प्वाइंट पॉइंट मैच करता है) पैटर्न मैच करता है

जो लोग लंबे समय से कंप्यूटर कर रहे हैं, इस तथ्य के लिए कि पैटर्न का उपयोग किया जाता है, बारीकी से देखने के लिए कुछ हो सकता है। तो यहां एक ऐसे बिंदु का उदाहरण दिया गया है set, जो तर्कों की परवाह किए बिना नामित किसी भी विधि से मेल खाता है:

call(* set(..))

तो यह एक काफी व्यापक बिंदु है और यह स्पष्ट होना चाहिए कि देखभाल के साथ इसे संभालने की सलाह दी जाती है (कोई दंडित इरादा नहीं) क्योंकि आप कई चीजों के लिए सलाह दे रहे हैं।

या बिल्ली, चलो नाम या हस्ताक्षर की परवाह किए बिना, हर चीज के लिए सलाह लागू करें !

execution(* *(..))

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

तो यहाँ एक अपेक्षाकृत सुरक्षित बिंदु की तरह दिखता है:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

यह स्पष्ट रूप से सलाह प्रदान करता है यदि किसी ऑब्जेक्ट पर नाम setXया विधि पाए जाते हैं। विधियाँ केवल s प्राप्त कर सकती हैं और वे होनी चाहिए । बहुत सुरक्षित लगता है, है ना? ठीक है, यह सुरक्षित है अगर वे तरीके मौजूद हैं और आपने सही सलाह लागू की है। यदि नहीं, तो बहुत बुरा; यह चुपचाप विफल रहता है।setYPointintvoid

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

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

इस प्रकार, लॉगिंग, डिबगिंग और ट्रेसिंग व्यवहार के महान उदाहरण हैं जो पहलुओं के लिए एकदम सही हैं, लेकिन सुरक्षा? नहीं। धागा सुरक्षा? नहीं।

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


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

2

एक स्थिति जिसमें एओपी केवल सभ्य और व्यावहारिक समाधान हो सकता है, जब आपके पास स्रोत कोड तक पहुंच नहीं है । लॉगिंग क्रॉस-कटिंग चिंता के पुराने पुराने उदाहरण का उपयोग करने के लिए:

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

और यदि आप वैसे भी एक लॉगिंग पहलू बना रहे हैं, तो आप एओपी के साथ लॉगिंग को लागू करने पर भी विचार कर सकते हैं और साथ ही साथ अपना कोड भी ट्राउट कर सकते हैं।


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

@Thorbjorn: लॉगिंग / डिबगिंग / ट्रेसिंग कार्यक्षमता के कई क्षेत्रों में से एक है, AOP इसमें मदद कर सकता है। मैंने इसे अपनी बात को स्पष्ट करने के लिए एक उदाहरण के रूप में इस्तेमाल किया। मैं जिस बिंदु को बनाने की कोशिश कर रहा हूं, वह यह है कि AOP आपको थर्ड पार्टी बायटेकोड पर अधिक नियंत्रण देता है।
जोसेफ ताननबौम

यकीन है, लेकिन मैं वास्तव में जानना चाहता था कि क्या एओपी लॉगिंग केवल प्रवेश-निकास लॉगिंग से अधिक कर सकता है?

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