Saya selalu dari pola pikir bahwa properti (yaitu, operasi set / get mereka) harus cepat / langsung dan bebas kegagalan. Anda seharusnya tidak perlu mencoba / mencari-cari atau mengatur properti.
Tapi saya sedang mencari beberapa cara untuk menerapkan keamanan berbasis peran pada properti beberapa objek. Misalnya properti Karyawan. Gaji. Beberapa solusi yang saya jalankan di yang orang lain telah coba (satu khususnya adalah contoh AOP di sini ) melibatkan melemparkan pengecualian jika accessor tidak memiliki izin yang tepat - tetapi ini bertentangan dengan aturan pribadi yang saya miliki untuk waktu yang lama sekarang.
Jadi saya bertanya: apakah saya salah? Apakah ada yang berubah? Sudahkah diterima bahwa properti harus dapat memberikan pengecualian?
sumber
Jawaban:
saat Anda menetapkan nilai properti, melemparkan pengecualian pada nilai yang tidak valid tidak masalah
mendapatkan nilai properti seharusnya (hampir) tidak pernah memberikan pengecualian
untuk akses berbasis peran, gunakan antarmuka / fasad yang berbeda / fasad; jangan biarkan orang melihat hal-hal yang tidak bisa mereka miliki!
sumber
Saya menganggap itu sebagian besar bentuk yang buruk tetapi bahkan Microsoft merekomendasikan untuk menggunakan pengecualian kadang-kadang. Contoh yang baik adalah Stream properti abstrak . Panjang . Sebagai pedoman, saya akan lebih peduli dengan menghindari efek samping pada getter dan membatasi efek samping pada setter.
sumber
Saya pasti akan berpendapat bahwa ada cacat dalam desain jika Anda merasa perlu untuk membuang pengecualian dari pengambil properti atau pengambil.
Properti adalah abstraksi yang mewakili sesuatu yang hanya berupa nilai . Dan Anda harus dapat menetapkan nilai tanpa takut hal itu dapat menimbulkan pengecualian. *
Jika pengaturan properti menghasilkan efek samping, yang seharusnya benar-benar diterapkan sebagai metode. Dan jika itu tidak menghasilkan efek samping, maka tidak terkecuali harus dibuang.
Salah satu contoh yang telah disebutkan dalam jawaban yang berbeda adalah
Stream.Position
properti. Ini memang menghasilkan efek samping, dan bisa menimbulkan pengecualian. Tapi setter properti ini pada dasarnya hanya pembungkusStream.Seek
yang bisa Anda hubungi.Secara pribadi, saya percaya bahwa posisi itu seharusnya bukan properti yang dapat ditulisi.
Contoh lain di mana Anda bisa tergoda untuk melempar pengecualian dari properti setter adalah dalam validasi data:
Tetapi ada solusi yang lebih baik untuk masalah ini. Perkenalkan jenis yang mewakili alamat email yang valid:
The
Email
Memastikan kelas yang tidak dapat memegang nilai yang bukan alamat email yang valid, dan kelas yang perlu toko email dibebaskan dari tugas memvalidasi mereka.Ini juga mengarah pada kohesi yang lebih tinggi (indikator desain perangkat lunak yang baik) - pengetahuan tentang apa alamat email itu, dan bagaimana alamat itu divalidasi, hanya ada di
Email
kelas, yang hanya memiliki keprihatinan itu.* ObjectDisposedException adalah satu-satunya pengecualian yang valid (tidak ada kata pun yang dimaksudkan) yang dapat saya pikirkan saat ini.
sumber
Saya tahu pertanyaan Anda khusus untuk .NET , tetapi karena C # berbagi beberapa sejarah dengan Java, saya pikir Anda mungkin tertarik. saya tidak menyiratkan bahwa karena sesuatu dilakukan di Jawa, itu harus dilakukan dalam C #. Saya tahu keduanya sangat berbeda, terutama dalam hal C # memiliki dukungan tingkat bahasa yang jauh lebih baik untuk properti. Saya hanya memberikan beberapa konteks dan perspektif.
Dari spesifikasi JavaBeans :
Tolong, ambil semua ini dengan sebutir garam. Spesifikasi JavaBeans sudah tua, dan Properti C # (IMO) merupakan peningkatan besar atas properti berbasis "penamaan konvensi" yang dimiliki Java. Saya hanya mencoba memberikan sedikit konteks, itu saja!
sumber
Titik properti adalah Prinsip Akses Seragam , yaitu bahwa nilai harus dapat diakses melalui antarmuka yang sama baik diimplementasikan oleh penyimpanan atau perhitungan. Jika properti Anda melempar pengecualian yang mewakili kondisi kesalahan di luar kendali programmer, jenis yang seharusnya ditangkap dan ditangani, Anda memaksa klien Anda untuk mengetahui bahwa nilai tersebut diperoleh melalui perhitungan.
Di sisi lain, saya tidak melihat masalah dengan menggunakan penegasan atau pengecualian seperti pernyataan yang dimaksudkan untuk menandakan penggunaan API yang salah kepada programmer daripada ditangkap dan ditangani. Dalam kasus ini, jawaban yang benar dari perspektif pengguna API bukan untuk menangani pengecualian (dengan demikian secara implisit peduli tentang apakah nilai diperoleh melalui perhitungan atau penyimpanan). Ini untuk memperbaiki kodenya sehingga objek tidak berakhir dalam keadaan tidak valid atau membuat Anda memperbaiki kode Anda sehingga pernyataan tidak menyala.
sumber
AFAIK, panduan ini terutama berasal dari proses pemikiran bahwa properti mungkin akhirnya digunakan pada desain waktu . (Misalnya properti Teks pada Kotak Teks) Jika properti melemparkan pengecualian ketika seorang desainer mencoba mengaksesnya, VS tidak akan memiliki hari yang baik. Anda akan mendapatkan banyak kesalahan hanya dengan mencoba menggunakan perancang dan untuk perancang UI, mereka tidak akan merender. Ini juga berlaku untuk waktu debug juga, meskipun apa yang akan Anda lihat dalam skenario pengecualian hanya "xxx Exception" dan itu tidak akan mengalahkan VS IIRC.
Untuk POCO, itu tidak akan benar-benar membahayakan, tetapi saya masih malu melakukannya sendiri. Saya pikir orang-orang akan ingin mengakses properti lebih sering, jadi mereka biasanya berbiaya rendah. Properti seharusnya tidak melakukan pekerjaan metode, mereka hanya harus mendapatkan / mengatur beberapa info dan dilakukan dengan itu sebagai aturan umum.
sumber
Meskipun banyak yang akan tergantung pada konteksnya, saya biasanya akan menghindari memasukkan segala jenis logika yang dapat pecah (termasuk pengecualian) ke properti. Sama seperti satu contoh, ada banyak hal yang dapat Anda (atau pustaka yang Anda gunakan) dapat lakukan yang menggunakan refleksi untuk beralih ke properti yang menghasilkan kesalahan yang tidak Anda antisipasi pada waktu desain.
Saya mengatakan secara umum karena mungkin ada saat-saat ketika Anda benar-benar ingin memblokir sesuatu tanpa terlalu khawatir tentang konsekuensinya. Keamanan Saya kira akan menjadi kasus klasik di sana.
sumber