"হাই, অ্যামিগো।"

"হ্যালো, ঋষি।"

"আজ আমি আপনাকে একটি নতুন এবং খুব আকর্ষণীয় বিষয় ব্যাখ্যা করব: গতিশীল প্রক্সি"

"জাভাতে একটি নির্দিষ্ট শ্রেণীর কার্যকারিতা পরিবর্তন করার বিভিন্ন উপায় রয়েছে..."

"প্রথম পদ্ধতি হল উত্তরাধিকার।"

"একটি ক্লাসের আচরণ পরিবর্তন করার সবচেয়ে সহজ উপায় হল একটি নতুন ক্লাস তৈরি করা যা মূল (বেস) ক্লাসের উত্তরাধিকারী হয় এবং এর পদ্ধতিগুলিকে ওভাররাইড করে। তারপরে, মূল ক্লাস ব্যবহার করার পরিবর্তে, আপনি প্রাপ্ত ক্লাস ব্যবহার করেন। উদাহরণস্বরূপ:"

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, যা সমস্ত মেথড কল ইন্টারসেপ্ট করতে পারে প্রক্সি অবজেক্টের সাথে যুক্ত । একটি প্রক্সি অবজেক্ট শুধুমাত্র ইন্টারফেস ব্যবহার করে তৈরি করা যেতে পারে।"

" ইনভোক - একটি পদ্ধতি বা ক্লাসের জন্য আদর্শ নাম যার প্রাথমিক কাজ হল শুধুমাত্র কিছু পদ্ধতিকে কল করা।"

" হ্যান্ডলার - এমন একটি ক্লাসের জন্য আদর্শ নাম যা কিছু ইভেন্ট পরিচালনা করে৷ উদাহরণস্বরূপ, একটি ক্লাস যা মাউস ক্লিকগুলি পরিচালনা করে তাকে 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 অবজেক্ট তৈরি করেছি, এবং তৈরি করার সময় এটিকে নতুন প্রক্সিইনস্ট্যান্স পদ্ধতিতে পাস করেছি। একটি প্রক্সি বস্তু।"

"হ্যাঁ, সব ঠিক।"

"এটি একটি খুব শক্তিশালী টুল। সাধারণত, এই প্রক্সিগুলি অন্য কম্পিউটারে শারীরিকভাবে চলমান প্রোগ্রামগুলিতে বস্তুর অনুকরণ করার জন্য তৈরি করা হয় ।  অথবা অ্যাক্সেস নিয়ন্ত্রণ করতে।"

"আপনি এই পদ্ধতিতে বর্তমান ব্যবহারকারীর অনুমতি পরীক্ষা করতে পারেন, ত্রুটিগুলি পরিচালনা করতে পারেন, লগ ত্রুটিগুলি এবং আরও অনেক কিছু করতে পারেন।"

"এখানে একটি উদাহরণ যেখানে আহ্বান পদ্ধতিটি আসল বস্তুর পদ্ধতিগুলিকেও কল করে:"

কোড
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;
 }
}

"আহ। ক্লাসলোডার এবং ইন্টারফেসের তালিকা। এটি প্রতিফলন থেকে কিছু, তাই না?"

"হ্যাঁ।"

"আমি দেখছি। ঠিক আছে, আমি মনে করি আমি একটি আদিম, অতি সাধারণ প্রক্সি অবজেক্ট তৈরি করতে পারি যদি আমার কখনো প্রয়োজন হয়।"

"তাহলে ডিয়েগোর সাথে চেক ইন করুন।"