เมื่อออกแบบคลาสควรมีความสอดคล้องในพฤติกรรมได้รับการสนับสนุนมากกว่าการฝึกเขียนโปรแกรมทั่วไป? เพื่อให้ตัวอย่างที่เฉพาะเจาะจง:
หลักการทั่วไปคือ: ถ้าคลาสเป็นเจ้าของวัตถุ (เช่นสร้างมัน) มันมีหน้าที่รับผิดชอบในการทำความสะอาดเมื่อทำเสร็จแล้ว ตัวอย่างที่เฉพาะเจาะจงจะอยู่ใน. NET ซึ่งหากคลาสของคุณเป็นเจ้าของIDisposable
วัตถุก็ควรกำจัดทิ้งเมื่อสิ้นสุดอายุการใช้งาน และหากคุณไม่ได้เป็นเจ้าของมันก็อย่าแตะต้องมัน
ตอนนี้ถ้าเราดูStreamWriter
คลาสใน. NET จากนั้นเราสามารถค้นหาได้ในเอกสารที่มันปิดสตรีมพื้นฐานเมื่อมันถูกปิด / จำหน่าย นี่เป็นสิ่งจำเป็นในกรณีที่StreamWriter
อินสแตนซ์ถูกสร้างขึ้นโดยส่งผ่านชื่อไฟล์ในฐานะผู้เขียนสร้างสตรีมไฟล์พื้นฐานและดังนั้นจึงจำเป็นต้องปิดมัน อย่างไรก็ตามสามารถส่งผ่านกระแสข้อมูลภายนอกที่ผู้เขียนปิดได้เช่นกัน
สิ่งนี้ทำให้ฉันรำคาญหลายครั้ง (ใช่ฉันรู้ว่าคุณสามารถสร้างเสื้อคลุมที่ไม่ปิด แต่นั่นไม่ใช่ประเด็น) แต่เห็นได้ชัดว่า Microsoft ได้ตัดสินใจว่าจะสอดคล้องกันมากขึ้นเพื่อปิดสตรีมไม่ว่าจะมาจากที่ใด
เมื่อฉันเข้ามาในรูปแบบดังกล่าวในหนึ่งในชั้นเรียนของฉันฉันมักจะสร้างownsFooBar
ธงที่ได้รับการตั้งค่าเป็นเท็จในกรณีที่FooBar
มีการฉีดผ่านคอนสตรัคและเป็นจริงอย่างอื่น วิธีนี้ความรับผิดชอบในการทำความสะอาดมันจะถูกส่งไปยังผู้โทรเมื่อเขาผ่านอินสแตนซ์อย่างชัดเจน
ตอนนี้ฉันสงสัยว่าบางทีความมั่นคงควรจะสนับสนุนการปฏิบัติที่ดีที่สุด (หรือการปฏิบัติที่ดีที่สุดของฉันอาจไม่ดี) มีข้อโต้แย้งใด ๆ สำหรับ / ต่อหรือไม่
แก้ไขเพื่อความกระจ่าง
ด้วย "ความสอดคล้อง" ฉันหมายถึง: พฤติกรรมที่สอดคล้องกันของชั้นเรียนจะต้องเป็นเจ้าของ (และปิดสตรีม) เสมอกับ "แนวปฏิบัติที่ดีที่สุด" เพื่อให้ได้กรรมสิทธิ์ในวัตถุเท่านั้นหากคุณสร้างขึ้นหรือโอนความเป็นเจ้าของอย่างชัดเจน
สำหรับตัวอย่างที่มันน่ารำคาญ:
สมมติว่าคุณมีสองคลาสที่กำหนด (จากห้องสมุดบุคคลที่สาม) ซึ่งยอมรับสตรีมเพื่อทำบางสิ่งกับมันเช่นการสร้างและประมวลผลข้อมูลบางส่วน:
public class DataProcessor
{
public Result ProcessData(Stream input)
{
using (var reader = new StreamReader(input))
{
...
}
}
}
public class DataSource
{
public void GetData(Stream output)
{
using (var writer = new StreamWriter(output))
{
....
}
}
}
ตอนนี้ฉันต้องการใช้แบบนี้:
Result ProcessSomething(DataSource source)
{
var processor = new DataProcessor();
...
var ms = new MemoryStream();
source.GetData(ms);
return processor.ProcessData(ms);
}
สิ่งนี้จะล้มเหลวโดยมีข้อยกเว้นCannot access a closed stream
ในตัวประมวลผลข้อมูล มันสร้างขึ้นเล็กน้อย แต่ควรแสดงให้เห็นถึงประเด็น มีหลายวิธีในการแก้ไข แต่อย่างไรก็ตามฉันรู้สึกว่าฉันแก้ไขบางสิ่งที่ไม่ควรทำ