Ini adalah pertanyaan desain umum, tapi saya fokus pada C # dan .NET karena itu adalah bahasa yang saya gunakan saat ini.
Haruskah saya membuat sendiri, kelas pengecualian baru, atau mengkooptasi kerangka kerja yang ada untuk tujuan yang sedikit berbeda?
Sebagai contoh, saya mendapati diri saya membutuhkan pengecualian yang menunjukkan anggota (yaitu, dari jenis misalnya) diharapkan, tetapi belum ditemukan saat membaca perakitan menggunakan Mono.Cecil
. Pustaka kelas dasar mendefinisikan pengecualian MissingMemberException
, yang tampaknya berkomunikasi persis apa yang saya inginkan, tetapi deskripsi mengatakan:
Pengecualian yang dilemparkan ketika ada upaya untuk secara dinamis mengakses anggota kelas yang tidak ada.
Yang tidak pas, karena saya tidak secara dinamis mengakses anggota, tetapi bekerja dengan majelis secara pasif.
sumber
Jawaban:
Secara umum
Pengecualian subklasifikasi adalah ide yang bagus untuk mengelompokkan pengecualian ke dalam keluarga atau pengelompokan yang mereka ikuti. Ini juga memungkinkan kode klien kesempatan untuk menangani pengecualian berdasarkan kesalahan spesifik atau lebih umum. Saya biasanya membagi pohon di suatu tempat dekat root antara kesalahan logis dan runtime (misalnya dalam C ++ the
std::runtime_error
vs.std::logic_error
).Mampu membedakan antara pengecualian sistem dan pengecualian aplikasi Anda juga merupakan ide yang bagus. Akan aneh jika kode klien mengawasi kegagalan sistem dari beberapa jenis tetapi menangkap kesalahan logis kode Anda (melalui kelas dasar).
Mengingat kasus ini dan C #
C # memiliki hierarki pengecualian yang kaya dan besar - Saya tidak akan mencoba mengambil kelas dasar terlalu jauh ke dalamnya. Mengikuti contoh Anda, sepertinya Anda melempar kesalahan logis (atau setidaknya kesalahan aplikasi), sehingga kelas dasar atau bahkan pengecualian itu akan mengisyaratkan kesalahan sistem. Pengecualian yang tepat dapat diperdebatkan, tetapi saya pikir dalam kasus ini itu bukan pilihan yang baik.
Hirarki
Saya akan membangun hierarki yang memungkinkan Anda untuk membedakan antara kesalahan sistem dan aplikasi dan kemudian lebih jauh antara runtime dan kesalahan logis. Jangan takut untuk menggunakan pengecualian dalam - menangkap kesalahan sistem dan membungkusnya dengan sesuatu yang lebih bermakna mengingat konteks di mana ia dilemparkan. Jangan berlebihan, fokuslah pada apa yang akan menjadi pengecualian utama. Pengecualian dapat memiliki deskripsi tekstual unik yang terkait dengannya - menggunakannya untuk memberikan pengguna lebih banyak detail atau petunjuk tentang apa yang harus dilakukan untuk memperbaiki masalah.
sumber
Jawabannya tentu saja "itu tergantung," tetapi mengingat kasus penggunaan Anda, saya akan mengatakan tidak. Inilah alasannya:
C # adalah bahasa yang luar biasa - goresan itu, yang terbaik - berorientasi objek. Sangat bagus, pada kenyataannya, bahwa saya kadang-kadang akan terjebak mencoba menerapkan visi fanatik murni tentang apa yang dimulai sebagai proyek sederhana. Itu tidak banyak terjadi pada saya ketika menulis JavaScript atau Objective-C atau kode PHP.
Ketika saya berada dalam "mode" ini, kelumpuhan semacam ini, salah satu gejala dapat menjadi obsesi dengan penanganan pengecualian dan obat generik serta meta-pemrograman. Terkadang ketiganya bersama. Jauh lebih mungkin menjadi masalah ketika saya mengerjakan sesuatu yang baru, relatif tidak dikenal, atau dengan spesifikasi dan tujuan yang jelek. Alih-alih menyibukkan diri dalam detail implementasi , saya pikir, mengapa mencoba membuat sesuatu yang dapat mengakomodasi sebagian besar skenario yang saya antisipasi secara wajar? Kemudian, ketika saya mencari tahu detailnya, fondasi akan diletakkan dan saya akan menulis banyak metode kecil yang gemuk, dan seterusnya. Mungkin orang lain akan bekerja pada kode UI, saya hanya akan memberi mereka layanan yang bagus dan kontrak ini ...
Sayangnya, itu belum terjadi pada saya. Yang cenderung terjadi adalah saya memulai jalur ini dengan mengerjakan "infrastruktur" - hal-hal seperti:
Castle.Windsor
Interceptors
dan membungkus panggilan ke anggota abstrak dengan penanganan pengecualianIRepository
,IUnitOfWork
,IDomainService
,ICrossCuttingValidation
, dllIFrameworkException
)Ketika Anda terpaku pada apakah deskripsi pengecualian cukup tepat untuk selera Anda, Anda benar-benar menolak beberapa fitur penting lainnya untuk diimplementasikan. Sifat pengecualian juga menunjukkan - ini bukan pengecualian yang didorong oleh peristiwa , ternyata jauh dari metodologi input (seperti UI atau pipa atau sesuatu) dan mungkin bersifat deterministik - karena Anda tidak dapat memprediksi apa yang akan dimasukkan oleh pengguna, tetapi Anda dapat memprediksi perakitan mana yang Anda pilih untuk memuat atau yang lainnya.
Omong-omong, jika uraiannya sangat mengganggu Anda, tidak bisakah Anda menulis metode ekstensi untuk menimpanya dalam ruang lingkup yang sesuai?
Jadi ini benar-benar hanya saya yang memproyeksikan abstraksi saya yang berlebihan dan analisis kelumpuhan kepada Anda, tetapi saya pikir itu mungkin tepat. Saya akan mengatakan bahwa untuk tetap di sisi aman, hanya subkelas
Exception
ketika:Exception
subclass yang adasumber
Dalam pandangan saya pengecualian khusus hanya masuk akal dalam 2 kasus:
1) Anda sedang mengembangkan Api
2) Anda menggunakannya dalam kode Anda untuk pulih dari kegagalan.
Dalam skenario lain apa pun, pengecualian bawaan harus memadai.
Dalam kasus Anda, Anda dapat menggunakan InvalidArgumentException
sumber