Ketika mendesain sebuah kelas haruskah konsistensi dalam perilaku lebih disukai daripada praktik pemrograman yang umum? Untuk memberikan contoh spesifik:
Sebuah konvensi umum adalah ini: Jika sebuah kelas memiliki objek (misalnya ia menciptakannya) ia bertanggung jawab untuk membersihkannya setelah selesai. Contoh spesifik akan di .NET bahwa jika kelas Anda memiliki IDisposable
objek itu harus membuangnya di akhir masa pakainya. Dan jika Anda tidak memilikinya maka jangan menyentuhnya.
Sekarang jika kita melihat StreamWriter
kelas di .NET maka kita dapat menemukan dalam dokumentasi bahwa itu menutup aliran yang mendasarinya ketika sedang ditutup / dibuang. Ini diperlukan dalam kasus di mana StreamWriter
instantiated dengan mengirimkan nama file sebagai penulis membuat aliran file yang mendasarinya dan karena itu perlu menutupnya. Namun seseorang juga dapat melewati aliran eksternal yang penulis juga tutup.
Ini telah mengganggu saya banyak kali (ya saya tahu Anda dapat membuat pembungkus non-penutupan tetapi bukan itu intinya) tetapi tampaknya Microsoft telah membuat keputusan bahwa lebih konsisten untuk selalu menutup aliran tidak peduli dari mana asalnya.
Ketika saya menemukan pola seperti itu di salah satu kelas saya, saya biasanya membuat ownsFooBar
bendera yang disetel ke false dalam kasus-kasus di mana FooBar
disuntikkan melalui konstruktor dan untuk benar sebaliknya. Dengan cara ini, tanggung jawab untuk membersihkannya diteruskan ke penelepon ketika dia memberikan contoh secara eksplisit.
Sekarang saya bertanya-tanya apakah mungkin konsistensi lebih disukai daripada praktik terbaik (atau mungkin praktik terbaik saya tidak sebagus itu)? Adakah argumen untuk / menentangnya?
Edit untuk klarifikasi
Dengan "konsistensi" yang saya maksud: Perilaku konsisten kelas selalu mengambil kepemilikan (dan menutup aliran) vs "praktik terbaik" untuk hanya mengambil kepemilikan atas suatu objek jika Anda membuatnya atau secara eksplisit memindahkan kepemilikan.
Adapun contoh di mana itu membuat:
Asumsikan Anda memiliki dua kelas yang diberikan (dari beberapa perpustakaan pihak ke-3) yang menerima aliran untuk melakukan sesuatu dengannya, seperti membuat dan memproses beberapa data:
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))
{
....
}
}
}
Sekarang saya ingin menggunakannya seperti ini:
Result ProcessSomething(DataSource source)
{
var processor = new DataProcessor();
...
var ms = new MemoryStream();
source.GetData(ms);
return processor.ProcessData(ms);
}
Ini akan gagal kecuali Cannot access a closed stream
di pengolah data. Ini sedikit dibangun tetapi harus menggambarkan intinya. Ada berbagai cara untuk memperbaikinya, namun saya merasa saya harus mengerjakan sesuatu yang seharusnya tidak perlu saya lakukan.