মৌলিকভাবে, প্রতিবিম্ব মানে আপনার প্রোগ্রামের কোডটিকে ডেটা হিসাবে ব্যবহার করা।
সুতরাং, যখন আপনার প্রোগ্রামের কোড ডেটা ব্যবহারের উত্স হয় তখন প্রতিবিম্বটি ব্যবহার করা ভাল ধারণা হতে পারে। (তবে ট্রেড অফ রয়েছে তাই এটি সর্বদা ভাল ধারণা নাও থাকতে পারে))
উদাহরণস্বরূপ, একটি সাধারণ শ্রেণি বিবেচনা করুন:
public class Foo {
public int value;
public string anotherValue;
}
এবং আপনি এটি থেকে এক্সএমএল তৈরি করতে চান। আপনি এক্সএমএল তৈরি করতে কোড লিখতে পারেন:
public XmlNode generateXml(Foo foo) {
XmlElement root = new XmlElement("Foo");
XmlElement valueElement = new XmlElement("value");
valueElement.add(new XmlText(Integer.toString(foo.value)));
root.add(valueElement);
XmlElement anotherValueElement = new XmlElement("anotherValue");
anotherValueElement.add(new XmlText(foo.anotherValue));
root.add(anotherValueElement);
return root;
}
তবে এটি অনেকগুলি বয়লারপ্লেট কোড এবং আপনি যখনই ক্লাস পরিবর্তন করেন তখন আপনাকে কোডটি আপডেট করতে হয়। সত্যিই, আপনি এই কোডটি কী করে তা বর্ণনা করতে পারেন
- শ্রেণীর নাম সহ একটি এক্সএমএল উপাদান তৈরি করুন
- শ্রেণীর প্রতিটি সম্পত্তি জন্য
- সম্পত্তির নাম সহ একটি এক্সএমএল উপাদান তৈরি করুন
- এক্সএমএল উপাদানটির মধ্যে সম্পত্তিটির মান রাখুন
- মূলটিতে এক্সএমএল উপাদান যুক্ত করুন
এটি একটি অ্যালগরিদম, এবং অ্যালগরিদমের ইনপুটটি বর্গ: আমাদের এটির নাম এবং এর বৈশিষ্ট্যগুলির নাম, প্রকার এবং মান প্রয়োজন। এখানেই প্রতিচ্ছবি আসে: এটি আপনাকে এই তথ্যে অ্যাক্সেস দেয়। জাভা আপনাকে এর পদ্ধতি ব্যবহার করে প্রকারের পরীক্ষা করতে দেয় toClass
ক্লাসের ।
আরও কিছু ব্যবহারের ক্ষেত্রে:
- কোনও ক্লাসের পদ্ধতির নামের উপর ভিত্তি করে URL এবং ওয়েব আর্গুমেন্টের ভিত্তিতে ইউআরএল প্যারামিটারের ভিত্তিতে একটি URL টি সংজ্ঞায়িত করুন
- শ্রেণীর কাঠামোটিকে গ্রাফিক্যুয়াল টাইপ সংজ্ঞায় রূপান্তর করুন
- শ্রেণীর প্রতিটি পদ্ধতিতে কল করুন যার নামটি ইউনিট পরীক্ষার কেস হিসাবে "পরীক্ষা" দিয়ে শুরু হয়
যাইহোক, পূর্ণ প্রতিবিম্বের অর্থ কেবল বিদ্যমান কোডের দিকে তাকানোই নয় (যা নিজে থেকেই "অন্তঃক্ষেত্র" হিসাবে পরিচিত is), কোড সংশোধন বা জেনারেট করে। জাভাতে এর জন্য দুটি প্রধান ব্যবহারের মামলা রয়েছে: প্রক্সি এবং উপহাস ocks
ধরা যাক আপনার একটি ইন্টারফেস রয়েছে:
public interface Froobnicator {
void froobnicateFruits(List<Fruit> fruits);
void froobnicateFuel(Fuel fuel);
// lots of other things to froobnicate
}
এবং আপনার একটি বাস্তবায়ন রয়েছে যা আকর্ষণীয় কিছু করে:
public class PowerFroobnicator implements Froobnicator {
// awesome implementations
}
এবং বাস্তবে আপনার একটি দ্বিতীয় বাস্তবায়নও রয়েছে:
public class EnergySaverFroobnicator implements Froobnicator {
// efficient implementations
}
এখন আপনি কিছু লগ আউটপুট চান; যখনই কোনও পদ্ধতি বলা হয় আপনি কেবল লগ বার্তা চান want আপনি প্রতিটি পদ্ধতিতে স্পষ্টভাবে লগ আউটপুট যুক্ত করতে পারেন, তবে এটি বিরক্তিকর হবে, এবং আপনাকে এটি দুটিবার করতে হবে; প্রতিটি বাস্তবায়নের জন্য একবার। (সুতরাং আপনি আরও বাস্তবায়ন যোগ করার সময় আরও বেশি।)
পরিবর্তে, আপনি একটি প্রক্সি লিখতে পারেন:
public class LoggingFroobnicator implements Froobnicator {
private Logger logger;
private Froobnicator inner;
// constructor that sets those two
public void froobnicateFruits(List<Fruit> fruits) {
logger.logDebug("froobnicateFruits called");
inner.froobnicateFruits(fruits);
}
public void froobnicateFuel(Fuel fuel) {
logger.logDebug("froobnicateFuel( called");
inner.froobnicateFuel(fuel);
}
// lots of other things to froobnicate
}
আবার, যদিও, একটি পুনরাবৃত্তি প্যাটার্ন রয়েছে যা একটি অ্যালগরিদম দ্বারা বর্ণনা করা যেতে পারে:
- লগার প্রক্সি এমন একটি শ্রেণি যা একটি ইন্টারফেস প্রয়োগ করে
- এটিতে এমন একটি কনস্ট্রাক্টর রয়েছে যা ইন্টারফেসের একটি অন্য বাস্তবায়ন গ্রহণ করে এবং একটি লগার
- ইন্টারফেসের প্রতিটি পদ্ধতির জন্য
- বাস্তবায়ন একটি বার্তা "$ পদ্ধতি নাম" লগ করে
- এবং তারপরে সমস্ত আর্গুমেন্টের পাশ দিয়ে অভ্যন্তরীণ ইন্টারফেসে একই পদ্ধতিটিকে কল করে
এবং এই অ্যালগরিদমের ইনপুট হ'ল ইন্টারফেস সংজ্ঞা।
প্রতিচ্ছবি আপনাকে এই অ্যালগরিদম ব্যবহার করে একটি নতুন শ্রেণি সংজ্ঞায়িত করতে দেয়। জাভা আপনাকে java.lang.reflect.Proxy
ক্লাসের পদ্ধতিগুলি ব্যবহার করে এটি করার অনুমতি দেয় এবং এমন গ্রন্থাগার রয়েছে যা আপনাকে আরও বেশি শক্তি দেয়।
তাহলে প্রতিবিম্বের ডাউনসাইট কী কী?
- আপনার কোডটি বোঝা শক্ত হয়ে যায়। আপনার বিধিবিধানের এক স্তর আপনার কোডের কংক্রিট প্রভাব থেকে আরও সরানো হয়েছে।
- আপনার কোডটি ডিবাগ করা শক্ত হয়ে যায়। বিশেষত কোড উত্পন্ন গ্রন্থাগারগুলির সাথে, কার্যকর করা কোডটি আপনার লেখা কোডটি নাও হতে পারে তবে আপনি যে কোডটি উত্পন্ন করেছেন এবং ডিবাগারটি আপনাকে সেই কোডটি প্রদর্শন করতে সক্ষম হতে পারে না (বা আপনাকে ব্রেকপয়েন্টগুলি রাখতে দেয়)।
- আপনার কোডটি ধীর হয়ে যায়। গতিশীলভাবে ধরণের তথ্য পড়ুন এবং হার্ড-কোডিং অ্যাক্সেসের পরিবর্তে রানটাইম হ্যান্ডেলগুলি দ্বারা ক্ষেত্রগুলিতে অ্যাক্সেস করা ধীর হয় is ডায়নামিক কোড জেনারেশন এই প্রভাবটি হ্রাস করতে পারে, ডিবাগ করা এমনকি আরও শক্ত হওয়ার জন্য।
- আপনার কোডটি আরও ভঙ্গুর হতে পারে। গতিশীল প্রতিচ্ছবি অ্যাক্সেস সংকলক দ্বারা টাইপ-চেক করা হয় না, রানটাইম সময় ত্রুটি নিক্ষেপ।