"হ্যালো, অ্যামিগো! আজ আমি আপনাকে BufferedInputStream ক্লাস সম্পর্কে কয়েকটি আকর্ষণীয় জিনিস বলব, তবে চলুন শুরু করা যাক « wrappers » এবং « চিনির ব্যাগ » দিয়ে।"

"আপনি «র্যাপার» এবং «চিনির ব্যাগ» দ্বারা কি বোঝাতে চান?"

"এগুলো রূপক। শোনো। তাই..."

"র্যাপার" (বা "ডেকোরেটর") নকশা প্যাটার্নটি উত্তরাধিকার ব্যবহার না করেই বস্তুর কার্যকারিতা বাড়ানোর জন্য একটি মোটামুটি সহজ এবং সুবিধাজনক প্রক্রিয়া।

বাফারডইনপুটস্ট্রিম - 1

ধরুন আমাদের দুটি পদ্ধতি সহ একটি Cat ক্লাস আছে: getName এবং setName:

জাভা কোড বর্ণনা
class Cat
{
 private String name;
 public Cat(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}
ক্যাট ক্লাসের দুটি পদ্ধতি রয়েছে: getName এবং setName
public static void main(String[] args)
{
 Cat cat = new Cat("Oscar");

 printName(cat);
}

public static void printName(Cat cat)
{
 System.out.println(cat.getName());
}
এটি কীভাবে ব্যবহার করা যেতে পারে তার একটি উদাহরণ।

"অস্কার" কনসোলে প্রদর্শিত হবে।

ধরুন আমাদের একটি বিড়াল বস্তুর উপর একটি পদ্ধতি কল বাধা দিতে হবে এবং সম্ভবত কিছু ছোট পরিবর্তন করতে হবে। এর জন্য, আমাদের এটিকে নিজস্ব র‍্যাপার ক্লাসে মোড়ানো দরকার ।

আমরা যদি কিছু বস্তুর উপর কল করার পদ্ধতির চারপাশে আমাদের নিজস্ব কোড "র্যাপ" করতে চাই, তাহলে আমাদের করতে হবে:

1) আমাদের নিজস্ব র‍্যাপার ক্লাস তৈরি করুন এবং একই ক্লাস/ইন্টারফেস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত বস্তুটি মোড়ানো হবে।

2) আমাদের ক্লাসের কনস্ট্রাক্টরের কাছে মোড়ানো অবজেক্টটি পাস করুন।

3) আমাদের নতুন ক্লাসে সমস্ত পদ্ধতি ওভাররাইড করুন। ওভাররাইড করা প্রতিটি পদ্ধতির ভিতরে মোড়ানো বস্তুর পদ্ধতিগুলিকে আহ্বান করুন।

4) আপনি যা চান তা পরিবর্তন করুন: পদ্ধতিটি যা কল করে তা পরিবর্তন করুন, তাদের পরামিতি পরিবর্তন করুন এবং/অথবা অন্য কিছু করুন।

নীচের উদাহরণে, আমরা একটি Cat অবজেক্টের getName পদ্ধতিতে কলগুলিকে ইন্টারসেপ্ট করি এবং এর রিটার্ন মানকে সামান্য পরিবর্তন করি।

জাভা কোড বর্ণনা
class Cat
{
 private String name;
 public Cat(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}
ক্যাট ক্লাসে দুটি পদ্ধতি রয়েছে: getName এবং setName।
class CatWrapper extends Cat
{
 private Cat original;
 public CatWrapper (Cat cat)
 {
  super(cat.getName());
  this.original = cat;
 }

 public String getName()
 {
  return "A cat named " + original.getName();
 }

 public void setName(String name)
 {
  original.setName(name);
 }
}
মোড়ক ক্লাস। ক্লাস মূল বস্তুর একটি রেফারেন্স ছাড়া কোনো তথ্য সংরক্ষণ করে না।
ক্লাসটি কনস্ট্রাক্টরের কাছে পাস করা আসল অবজেক্টে (setName) কল "থ্রো" করতে সক্ষম। এটি এই কলগুলিকে "ক্যাচ" করতে পারে এবং তাদের পরামিতি এবং/অথবা ফলাফলগুলি পরিবর্তন করতে পারে
public static void main(String[] args)
{
 Cat cat = new Cat("Oscar");
 Cat catWrap = new CatWrapper (cat);
 printName(catWrap);
}

public static void printName(Cat named)
{
 System.out.println(named.getName());
}
এটি কীভাবে ব্যবহার করা যেতে পারে তার একটি উদাহরণ।

"অস্কার নামের একটি বিড়াল"।
কনসোলে প্রদর্শিত হবে

অন্য কথায়, আমরা নিঃশব্দে প্রতিটি আসল বস্তুকে একটি মোড়ক বস্তু দিয়ে প্রতিস্থাপন করি, যা মূল বস্তুর একটি লিঙ্ক পায়। র‍্যাপারের সমস্ত মেথড কল মূল বস্তুতে ফরোয়ার্ড করা হয় এবং সবকিছু ঘড়ির কাঁটার মতো চলে৷

"আমি এটা পছন্দ করি। সমাধানটি সহজ এবং কার্যকরী।"

"আমি আপনাকে «চিনির ব্যাগ» সম্পর্কেও বলব। এটি একটি নকশার প্যাটার্নের পরিবর্তে একটি রূপক। বাফার এবং বাফারিং শব্দের একটি রূপক। বাফারিং কী এবং কেন আমাদের এটি প্রয়োজন?"

বাফারডইনপুটস্ট্রিম - 2

ধরা যাক আজ ঋষির রান্না করার পালা, আর আপনি তাকে সাহায্য করছেন। ঋষি এখনো আসেনি, কিন্তু আমি চা খেতে চাই। আমি আপনাকে এক চামচ চিনি আনতে বলি। আপনি বেসমেন্টে যান এবং একটি চিনির ব্যাগ খুঁজে পান। আপনি আমাকে পুরো ব্যাগটি আনতে পারেন, কিন্তু আমার ব্যাগের প্রয়োজন নেই। আমার শুধু এক চামচ দরকার। তারপর, একটি ভাল রোবটের মতো, আপনি এক চামচ নিন এবং আমার কাছে নিয়ে আসুন। আমি এটি চায়ে যোগ করি, কিন্তু এটি এখনও যথেষ্ট মিষ্টি নয়। এবং আমি আপনাকে আরও একটি নিয়ে আসতে বলছি। আপনি আবার বেসমেন্টে যান এবং আরেকটি চামচ নিয়ে আসুন। তারপর এলি আসে, এবং আমি আপনাকে তার জন্য চিনি আনতে বলি... এই সব অনেক সময় নেয় এবং অকার্যকর।

ঋষি আসে, এই সব দেখে, এবং আপনাকে একটি চিনির বাটি পূর্ণ চিনি আনতে বলে। তারপর এলি এবং আমি ঋষিকে চিনির জন্য জিজ্ঞাসা করতে শুরু করি। তিনি কেবল চিনির বাটি থেকে আমাদের এটি পরিবেশন করেন এবং এটিই সব।

ঋষি দেখানোর পরে যা ঘটেছিল তাকে বাফারিং বলা হয় : চিনির বাটিটি একটি বাফার। বাফারিংয়ের জন্য ধন্যবাদ, "ক্লায়েন্টরা" একটি বাফার থেকে ছোট অংশে ডেটা পড়তে পারে , যখন বাফার, সময় এবং প্রচেষ্টা বাঁচানোর জন্য, উত্স থেকে সেগুলিকে বড় অংশে পড়ে ৷

"এটি একটি দুর্দান্ত উদাহরণ, কিম। আমি পুরোপুরি বুঝতে পেরেছি। এক চামচ চিনির অনুরোধ একটি স্রোত থেকে এক বাইট পড়ার মতো।"

"ঠিকভাবে। বাফারড ইনপুটস্ট্রিম ক্লাস হল একটি বাফার করা র‍্যাপারের একটি ধ্রুপদী উদাহরণ। এটি ইনপুটস্ট্রীম ক্লাসকে মোড়ানো হয়। এটি একটি বাফারে বড় ব্লকে মূল ইনপুটস্ট্রিম থেকে ডেটা পড়ে এবং তারপরে এটিকে বাফার থেকে টুকরো টুকরো করে বের করে দেয় এটি থেকে পড়ুন।"

"খুব ভালো। সব পরিষ্কার। লেখার জন্য কি বাফার আছে?"

"ওহ, নিশ্চিত।"

"হয়তো একটা উদাহরণ?"

"একটি ট্র্যাশ ক্যানের কল্পনা করুন। প্রতিবার ময়লা জ্বাল দেওয়ার জন্য বাইরে যাওয়ার পরিবর্তে, আপনি কেবল এটিকে ট্র্যাশ ক্যানের মধ্যে ফেলে দিন। তারপরে বুব্বা প্রতি দুই সপ্তাহে একবার ক্যানটি বাইরে নিয়ে যায়। একটি ক্লাসিক বাফার।"

"কি মজার! আর এক ব্যাগ চিনির চেয়েও অনেক বেশি পরিষ্কার।"

"এবং flush() পদ্ধতিটি এখনই আবর্জনা বের করার মতো। অতিথিরা আসার আগে আপনি এটি ব্যবহার করতে পারেন।"