CodeGym /หลักสูตร /จาวาคอร์ /บัฟเฟอร์อินพุตสตรีม

บัฟเฟอร์อินพุตสตรีม

จาวาคอร์
ระดับ , บทเรียน
มีอยู่

"สวัสดี Amigo! วันนี้ฉันจะบอกคุณถึงสิ่งที่น่าสนใจบางอย่างเกี่ยวกับคลาส BufferedInputStream แต่ขอเริ่มด้วย « กระดาษห่อ » และ « ถุงน้ำตาล »"

"คำว่า "กระดาษห่อ" และ "ถุงน้ำตาล" หมายความว่าอย่างไร"

"นี่เป็นอุปมาอุปไมย ฟังนะ ดังนั้น..."

รูปแบบการออกแบบ «wrapper» (หรือ «มัณฑนากร») เป็นกลไกที่ค่อนข้างง่ายและสะดวกสำหรับการขยายการทำงานของวัตถุโดยไม่ต้องใช้การสืบทอด

BufferedInputStream - 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;
 }
}
คลาส Cat มีสองเมธอด: 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());
}
ตัวอย่างของวิธีการใช้

«ออสการ์» จะแสดงบนคอนโซล

สมมติว่าเราจำเป็นต้องสกัดกั้นการเรียกใช้เมธอดบน วัตถุ catและอาจทำการเปลี่ยนแปลงเล็กน้อย สำหรับสิ่งนี้ เราจำเป็นต้องห่อมันในคลาสของกระดาษห่อของมันเอง

ถ้าเราต้องการ"ล้อม"โค้ดของเราเองไว้รอบเมธอดที่เรียกใช้ออบเจกต์บางอย่าง เราจำเป็นต้อง:

1)สร้างคลาส wrapper ของเราเองและสืบทอดจากคลาส / อินเตอร์เฟสเดียวกันกับวัตถุที่จะห่อ

2)ส่งวัตถุที่จะห่อไปยังตัวสร้างคลาสของเรา

3)ลบล้างเมธอดทั้งหมดในคลาสใหม่ของเรา เรียกใช้เมธอดของออบเจกต์ที่ห่อไว้ในแต่ละเมธอดที่ถูกแทนที่

4)ทำการเปลี่ยนแปลงตามที่คุณต้องการ: เปลี่ยนสิ่งที่เรียกใช้เมธอด เปลี่ยนพารามิเตอร์ และ/หรือทำอย่างอื่น

ในตัวอย่างด้านล่าง เราสกัดกั้นการเรียกเมธอด getName ของวัตถุ Cat และเปลี่ยนค่าส่งคืนเล็กน้อย

รหัสจาวา คำอธิบาย
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;
 }
}
คลาส Cat มีสองเมธอด: 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());
}
ตัวอย่างของวิธีการใช้

«แมวชื่อออสการ์».
จะแสดงบนคอนโซล

กล่าวอีกนัยหนึ่ง เราแทนที่วัตถุดั้งเดิมแต่ละชิ้นอย่างเงียบ ๆ ด้วยวัตถุห่อหุ้ม ซึ่งได้รับลิงก์ไปยังวัตถุดั้งเดิม การเรียกใช้เมธอดทั้งหมดบน wrapper จะถูกส่งต่อไปยังออบเจกต์ดั้งเดิมและทุกอย่างจะทำงานเหมือนเครื่องจักร

"ฉันชอบ วิธีแก้ปัญหานั้นง่ายและใช้งานได้จริง"

"ฉันจะบอกคุณเกี่ยวกับ «ถุงน้ำตาล» ด้วย นี่เป็นคำเปรียบเทียบมากกว่ารูปแบบการออกแบบ คำอุปมาของคำว่า buffer และ buffering อะไรคือ buffering และทำไมเราถึงต้องการมัน"

BufferedInputStream - 2

สมมติว่าวันนี้ถึงตาของฤๅษีทำอาหารและคุณช่วยเขา ฤๅษียังไม่มา แต่ข้าอยากดื่มชา ฉันขอให้คุณนำน้ำตาลหนึ่งช้อนเต็มมาให้ฉัน คุณไปที่ชั้นใต้ดินและหาถุงน้ำตาล คุณสามารถนำกระเป๋าทั้งใบมาให้ฉัน แต่ฉันไม่ต้องการถุงนั้น ฉันต้องการเพียงหนึ่งช้อนเต็ม แล้วเหมือนหุ่นที่ดี คุณเอาหนึ่งช้อนเต็มแล้วเอามาให้ฉัน ฉันเพิ่มมันลงในชา ​​แต่ก็ยังหวานไม่พอ และฉันขอให้คุณนำมาให้ฉันอีกครั้ง คุณไปที่ห้องใต้ดินอีกครั้งและนำอีกช้อนเต็ม จากนั้น Ellie ก็เข้ามา และฉันขอให้คุณนำน้ำตาลมาให้เธอ... ทั้งหมดนี้ใช้เวลานานเกินไปและไม่มีประสิทธิภาพ

ฤๅษีมาเห็นเข้าจึงขอให้นำขันน้ำตาลเต็มขันมาให้เขา จากนั้นฉันกับเอลลี่ก็เริ่มขอน้ำตาลกับริชิ เขาเพียงแค่เสิร์ฟให้เราจากชามน้ำตาลเท่านั้น และนั่นคือทั้งหมด

สิ่งที่เกิดขึ้นหลังจากฤๅษีปรากฏตัวเรียกว่าบัฟเฟอร์ : ชามน้ำตาลเป็นบัฟเฟอร์ ด้วยการบัฟเฟอร์ "ไคลเอนต์" สามารถอ่านข้อมูลจากบัฟเฟอร์เป็นส่วนเล็กๆในขณะที่บัฟเฟอร์เพื่อประหยัดเวลาและความพยายาม อ่านข้อมูลจากแหล่งที่มาเป็นส่วนใหญ่

"นั่นเป็นตัวอย่างที่ดี คิม ฉันเข้าใจดี การขอน้ำตาลหนึ่งช้อนเต็มก็เหมือนการอ่านหนึ่งไบต์จากลำธาร"

"ถูกต้อง คลาสBufferedInputStreamเป็นตัวอย่างคลาสสิกของ wrapper ที่มีบัฟเฟอร์ มันล้อมคลาส InputStream โดยจะอ่านข้อมูลจาก InputStream ดั้งเดิมในบล็อกขนาดใหญ่ลงในบัฟเฟอร์ แล้วดึงออกจากบัฟเฟอร์ทีละชิ้นในขณะที่เรา อ่านจากมัน”

"ดีมาก ทุกอย่างชัดเจน มีบัฟเฟอร์สำหรับเขียนหรือไม่"

"อ๋อ แน่นอน"

“ยกตัวอย่างได้ไหม”

"ลองนึกภาพถังขยะ แทนที่จะออกไปข้างนอกเพื่อใส่ขยะในเตาเผาทุกครั้ง คุณก็แค่โยนมันลงถังขยะ จากนั้น Bubba จะนำกระป๋องออกไปข้างนอกทุกสองสัปดาห์ บัฟเฟอร์แบบคลาสสิก"

"น่าสนใจจัง! แถมยังใสยิ่งกว่าน้ำตาลหนึ่งถุงเสียอีก"

"และวิธีการ flush() ก็เหมือนกับการกำจัดขยะทันที คุณสามารถใช้ก่อนที่แขกจะมาถึง"

ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION