"हाय, अमिगो."

"हॅलो, ऋषी."

"आज मी तुम्हाला एक नवीन आणि अतिशय मनोरंजक विषय समजावून सांगेन: डायनॅमिक प्रॉक्सी" .

"जावाकडे विशिष्ट वर्गाची कार्यक्षमता बदलण्याचे अनेक मार्ग आहेत..."

"पहिली पद्धत वारसा आहे."

"वर्गाचे वर्तन बदलण्याचा सर्वात सोपा मार्ग म्हणजे मूळ (बेस) वर्गाचा वारसा घेणारा नवीन वर्ग तयार करणे आणि त्याच्या पद्धती ओव्हरराइड करणे. नंतर, मूळ वर्ग वापरण्याऐवजी, तुम्ही व्युत्पन्न वर्ग वापरा. ​​उदाहरणार्थ:"

Reader reader = new UserCustomReader();

"दुसरी पद्धत म्हणजे रॅपर क्लास वापरणे."

" BufferedReader हे या प्रकारच्या वर्गाचे एक उदाहरण आहे. प्रथम, ते रीडरचे वारसा घेते . दुसऱ्या शब्दांत, ते रीडरऐवजी वापरले जाऊ शकते. दुसरे, ते सर्व कॉल मूळ रीडर ऑब्जेक्टवर पुनर्निर्देशित करते, जे BufferedReader ऑब्जेक्टच्या कन्स्ट्रक्टरकडे पास केले जाणे आवश्यक आहे. . उदाहरणार्थ:"

Reader readerOriginal = new UserCustomReader();
Reader reader = new BufferedReader(readerOriginal);

"तिसरी पद्धत म्हणजे डायनॅमिक प्रॉक्सी (प्रॉक्सी) तयार करणे."

"जावा (java.lang.reflect.Proxy) मध्ये एक विशेष वर्ग आहे जो तुम्हाला प्रोग्राम एक्झिक्यूशन दरम्यान (डायनॅमिकली) ऑब्जेक्ट तयार करू देतो, त्यासाठी वेगळा क्लास तयार न करता."

"हे करणे खूप सोपे आहे:"

Reader reader = (Reader)Proxy.newProxyInstance();

"ते आधीच माझ्यासाठी काहीतरी नवीन आहे!"

"परंतु नक्कीच, आम्हाला कोणत्याही पद्धती नसलेल्या ऑब्जेक्टची आवश्यकता नाही. आम्हाला पद्धती असण्यासाठी ऑब्जेक्टची आवश्यकता आहे आणि आम्हाला पाहिजे ते करण्यासाठी आम्हाला त्यांची आवश्यकता आहे. जावा या InvocationHandler नावाचा एक विशेष इंटरफेस वापरते, जे सर्व मेथड कॉल्स इंटरसेप्ट करू शकते प्रॉक्सी ऑब्जेक्टशी संबंधित . एक प्रॉक्सी ऑब्जेक्ट फक्त इंटरफेस वापरून तयार केला जाऊ शकतो."

" Invoke - हे एखाद्या पद्धतीचे किंवा वर्गाचे मानक नाव आहे ज्याचे प्राथमिक कार्य फक्त काही पद्धत कॉल करणे आहे."

" हँडलर - काही इव्हेंट हाताळणाऱ्या वर्गाचे मानक नाव आहे. उदाहरणार्थ, माऊस क्लिक हाताळणाऱ्या वर्गाला MouseClickHandler, इ.

"InvocationHandler इंटरफेसमध्ये एकच इनव्होक पद्धत आहे, ज्यावर प्रॉक्सी ऑब्जेक्टवर सर्व कॉल निर्देशित केले जातात . उदाहरणार्थ:"

कोड
Reader reader = (Reader)Proxy.newProxyInstance(new CustomInvocationHandler());
reader.close();
class CustomInvocationHandler implements InvocationHandler
{
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 {
  System.out.println("yes!");
  return null;
 }
}

" रीडरला कॉल करताना . क्लोज () पद्धत, इनव्होक पद्धत कॉल केली जाईल, आणि स्क्रीन 'होय!' प्रदर्शित करेल."

"म्हणून, आम्ही एक CustomInvocationHandler, क्लास घोषित केला, आणि InvocationHandler इंटरफेस आणि त्याची इनव्होक पद्धत लागू केली. जेव्हा इनव्होक पद्धत कॉल केली जाते, तेव्हा ती 'होय!' दर्शवते. त्यानंतर आम्ही एक CustomInvocationHandler ऑब्जेक्ट तयार केला आणि तयार करताना तो नवीनProxyInstance पद्धतीवर पास केला. एक प्रॉक्सी ऑब्जेक्ट."

"हो, ते सर्व बरोबर आहे."

"हे एक अतिशय शक्तिशाली साधन आहे. सहसा, हे प्रॉक्सी इतर संगणकावर भौतिकरित्या चालू असलेल्या प्रोग्राममधील ऑब्जेक्ट्सचे अनुकरण करण्यासाठी तयार केले जातात .  किंवा प्रवेश नियंत्रित करण्यासाठी."

"या पद्धतीत तुम्ही सध्याच्या वापरकर्त्याच्या परवानग्या तपासू शकता, त्रुटी हाताळू शकता, लॉग त्रुटी आणि बरेच काही करू शकता."

"येथे एक उदाहरण आहे जेथे इनव्होक पद्धत मूळ ऑब्जेक्टच्या पद्धतींना देखील कॉल करते:"

कोड
Reader original = new UserCustomReader();

Reader reader = (Reader)Proxy.newProxyInstance(new CustomInvocationHandler(original));
reader.close();
class CustomInvocationHandler implements InvocationHandler
{
 private Reader readerOriginal;

 CustomInvocationHandler(Reader readerOriginal)
 {
  this.readerOriginal = readerOriginal;
 }

 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 {
  if (method.getName().equals("close"))
  {
   System.out.println("Reader closed!");
  }

  // This calls the readerOriginal object's close method.
  // The method's name and a description of its parameters are stored in the method variable.
  return method.invoke(readerOriginal, args);
 }
}

"या उदाहरणात दोन विशेष वैशिष्ट्ये आहेत."

"प्रथम, «मूळ» रीडर ऑब्जेक्ट कन्स्ट्रक्टरकडे पाठवला जातो आणि त्याचा संदर्भ CustomInvocationHandler मध्ये सेव्ह केला जातो . "

"दुसरे, आम्ही याच पद्धतीला पुन्हा आमंत्रण पद्धतीमध्ये कॉल करतो, परंतु यावेळी «मूळ» ऑब्जेक्टवर."

"आह. दुसऱ्या शब्दांत, ही शेवटची ओळ त्याच पद्धतीला कॉल करते, परंतु मूळ ऑब्जेक्टवर:"

return method.invoke(readerOriginal, args);

"हो."

"मी असे म्हणणार नाही की ते अगदी स्पष्ट आहे, परंतु तरीही ते समजण्यासारखे आहे. किंवा असे दिसते."

"छान. मग आणखी एक गोष्ट. नवीन प्रॉक्सी इंस्टन्स पद्धतीमध्ये, प्रॉक्सी ऑब्जेक्ट तयार करण्यासाठी तुम्हाला थोडी अधिक गृहनिर्माण माहिती पास करणे आवश्यक आहे. परंतु आम्ही राक्षसी प्रॉक्सी वस्तू तयार करत नसल्यामुळे, ही माहिती मूळ वर्गातूनच सहज मिळवता येते. "

"हे दुसरे उदाहरण आहे:"

कोड
Reader original = new UserCustomReader();

ClassLoader classLoader = original.getClass().getClassLoader();
Class<?>[] interfaces = original.getClass().getInterfaces();
CustomInvocationHandler invocationHandler = new CustomInvocationHandler(original);

Reader reader = (Reader)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
class CustomInvocationHandler implements InvocationHandler
{
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 {
  return null;
 }
}

"अहो. क्लासलोडर आणि इंटरफेसची यादी. हे रिफ्लेक्शनमधून काहीतरी आहे, नाही का?"

"हो."

"मी पाहतो. बरं, मला वाटतं की मला कधी गरज पडल्यास मी एक आदिम, सुपर सिंपल प्रॉक्सी ऑब्जेक्ट तयार करू शकतो."

"मग डिएगो बरोबर चेक इन करा."