"Helo, Amigo! Hari ini saya akan memberitahu anda beberapa perkara menarik tentang kelas BufferedInputStream, tetapi mari kita mulakan dengan « pembungkus » dan « beg gula »."

"Apakah yang anda maksudkan dengan «pembungkus» dan «beg gula»?"

"Ini adalah metafora. Dengar. Jadi…"

Corak reka bentuk «pembungkus» (atau «penghias») ialah mekanisme yang agak mudah dan mudah untuk melanjutkan fungsi objek tanpa menggunakan warisan.

BufferedInputStream - 1

Katakan kita mempunyai kelas Cat dengan dua kaedah: getName dan setName:

kod Java Penerangan
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;
 }
}
Kelas Cat mempunyai dua kaedah: getName dan 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());
}
Contoh bagaimana ia boleh digunakan.

«Oscar» akan dipaparkan pada konsol.

Katakan kita perlu memintas panggilan kaedah pada objek kucing dan mungkin membuat beberapa perubahan kecil. Untuk ini, kita perlu membungkusnya dalam kelas pembalutnya sendiri.

Jika kita ingin "membungkus" kod kita sendiri di sekitar kaedah panggilan pada beberapa objek, maka kita perlu:

1) Buat kelas pembalut kita sendiri dan warisi dari kelas/antara muka yang sama dengan objek yang akan dibalut.

2) Hantar objek yang akan dibalut ke pembina kelas kami.

3) Gantikan semua kaedah dalam kelas baharu kami. Panggil kaedah objek yang dibalut di dalam setiap kaedah yang diganti.

4) Buat apa sahaja perubahan yang anda mahu: tukar perkara yang dilakukan oleh kaedah, tukar parameternya dan/atau lakukan sesuatu yang lain.

Dalam contoh di bawah, kami memintas panggilan ke kaedah getName objek Cat dan menukar sedikit nilai pulangannya.

kod Java Penerangan
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;
 }
}
Kelas Cat mengandungi dua kaedah: getName dan 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);
 }
}
Kelas pembalut. Kelas tidak menyimpan sebarang data kecuali rujukan kepada objek asal.
Kelas dapat "membuang" panggilan ke objek asal (setName) yang diserahkan kepada pembina. Ia juga boleh "menangkap" panggilan ini dan mengubah suai parameter dan/atau keputusannya .
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());
}
Contoh bagaimana ia boleh digunakan.

"Kucing bernama Oscar".
akan dipaparkan pada konsol

Dalam erti kata lain, kami secara senyap-senyap menggantikan setiap objek asal dengan objek pembalut, yang menerima pautan ke objek asal. Semua panggilan kaedah pada pembalut dimajukan ke objek asal, dan semuanya berjalan seperti gerak jam.

"Saya suka. Penyelesaiannya mudah dan berfungsi."

"Saya juga akan memberitahu anda tentang «beg gula». Ini adalah metafora dan bukannya corak reka bentuk. Metafora untuk perkataan buffer dan buffering. Apakah penimbal dan mengapa kita memerlukannya?"

BufferedInputStream - 2

Katakan hari ini giliran Rishi untuk memasak, dan anda membantunya. Rishi belum sampai, tapi saya nak minum teh. Saya minta awak bawakan saya satu sudu gula. Anda pergi ke ruang bawah tanah dan mencari beg gula. Anda boleh membawa saya keseluruhan beg, tetapi saya tidak memerlukan beg itu. Saya hanya perlukan satu sudu. Kemudian, seperti robot yang baik, anda mengambil satu sudu dan membawanya kepada saya. Saya menambahnya ke dalam teh, tetapi ia masih tidak cukup manis. Dan saya minta awak bawakan saya satu lagi. Anda sekali lagi pergi ke ruang bawah tanah dan bawa satu sudu lagi. Kemudian Ellie datang, dan saya minta awak bawakan gula untuknya... Semua ini mengambil masa terlalu lama dan tidak cekap.

Rishi datang, melihat semua ini, dan meminta anda membawakan mangkuk gula yang penuh dengan gula. Kemudian Ellie dan saya mula meminta Rishi untuk gula. Dia hanya menghidangkannya kepada kami dari mangkuk gula, dan itu sahaja.

Apa yang berlaku selepas Rishi muncul dipanggil penimbal : mangkuk gula ialah penimbal. Terima kasih kepada penimbalan, "pelanggan" boleh membaca data daripada penimbal dalam bahagian kecil , manakala penimbal, untuk menjimatkan masa dan usaha, membacanya daripada sumber dalam bahagian yang besar .

"Itu contoh yang bagus, Kim. Saya faham dengan sempurna. Permintaan untuk sesudu gula adalah seperti membaca satu bait daripada aliran."

"Tepat sekali. Kelas BufferedInputStream ialah contoh klasik pembungkus penimbal. Ia membungkus kelas InputStream. Ia membaca data daripada InputStream asal dalam blok besar ke dalam penimbal, dan kemudian menariknya keluar daripada penimbal sekeping demi sekeping semasa kita baca daripadanya."

"Sangat bagus. Semuanya jelas. Adakah terdapat penampan untuk menulis?"

"Boleh."

"Mungkin satu contoh?"

"Bayangkan sebuah tong sampah. Daripada pergi ke luar untuk memasukkan sampah ke dalam insinerator setiap kali, anda hanya membuangnya ke dalam tong sampah. Kemudian Bubba membawa tong itu ke luar setiap dua minggu sekali. Penampan klasik."

"Betapa menarik! Dan jauh lebih jelas daripada beg gula, dengan cara itu."

"Dan kaedah flush() adalah seperti membuang sampah dengan segera. Anda boleh menggunakannya sebelum tetamu tiba."