Menggunakan pernyataan versus melempar pengecualian?

38

Seringkali ketika saya menulis suatu fungsi saya ingin memastikan input ke dalamnya valid untuk mendeteksi kesalahan sedini mungkin (saya percaya ini disebut prasyarat). Ketika sebuah prasyarat gagal, saya selalu melemparkan pengecualian. Tetapi saya mulai ragu apakah ini praktik terbaik dan jika tidak, pernyataan akan lebih tepat.

Jadi kapan saya harus melakukan yang: kapan tepat untuk menggunakan pernyataan dan kapan tepat untuk melemparkan pengecualian?

Gablin
sumber
3
Saya pikir pertanyaan ini harus ditanyakan pada stackoverflow, meskipun mungkin telah ditanyakan selusin kali di sana, sehingga Anda mungkin sudah menemukan banyak jawaban di sana.
user281377

Jawaban:

50

Pernyataan hanya boleh digunakan untuk memverifikasi kondisi yang secara logis tidak mungkin salah (baca: cek kewarasan). Ketentuan ini seharusnya hanya didasarkan pada input yang dihasilkan oleh kode Anda sendiri. Setiap pemeriksaan berdasarkan input eksternal harus menggunakan pengecualian.

Aturan sederhana yang cenderung saya ikuti adalah memverifikasi argumen fungsi pribadi dengan menegaskan, dan menggunakan pengecualian untuk argumen fungsi publik / yang dilindungi.

Catatan untuk memikirkan nama
sumber
Poin bagus tentang menggunakan pengecualian untuk input eksternal. Saya juga menambahkan output untuk itu - masalah ketika mencoba membuat / menulis ke file / database dll
ChrisF
13
Dan mau tak mau Anda akan menemukan pernyataan-pernyataan itu dipicu dalam produksi. +1 untuk memverifikasi barang pribadi dengan penegasan! Mungkin Anda bisa mengatakan "gunakan konfirmasi ketika Anda memegang kendali penuh atas input"?
Frank Shearar
1
Di java, setidaknya, Anda harus mengaktifkan cek asersi dengan parameter baris perintah -ea. Ini berarti asersi secara efektif no-ops, kecuali jika Anda mengaktifkannya secara eksplisit.
Bill Michell
29

Penegasan digunakan untuk menemukan kesalahan pemrograman. Program Anda harus bekerja dengan baik ketika semua pernyataan dihapus.

Pengecualian, di sisi lain, adalah untuk situasi yang dapat terjadi bahkan ketika programnya sempurna; mereka disebabkan oleh pengaruh eksternal, seperti perangkat keras, jaringan, pengguna dll.

pengguna281377
sumber
Ini adalah cara yang cukup bagus untuk menjelaskannya. Jika pengguna memasukkan sesuatu yang salah, lempar pengecualian. Jika input sudah benar tetapi masih ada yang salah, berikan pernyataan.
Mateen Ulhaq
3

Praktik pemrograman tipikal adalah mengumpulkan pernyataan dari produksi / rilis build. Asersi hanya akan membantu selama pengujian internal untuk menangkap kegagalan asumsi. Anda seharusnya tidak menganggap perilaku agen eksternal, jadi Anda tidak boleh menegaskan tentang peristiwa dari jaringan atau pengguna. Juga merupakan praktik yang baik untuk menulis kode penanganan untuk produksi jika seandainya pernyataan gagal.

Misalnya dalam C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Pengecualian dimaksudkan untuk dibangun di dalam bangunan produksi. Alternatif pengecualian adalah kesalahan pengembalian dan bukan asersi.

ayah
sumber
2
Saya tidak berpikir itu ide yang baik untuk menempatkan perilaku anggun di belakang pernyataan untuk kondisi yang sama. Tidak dapat dihindari, karena perilaku anggun hanya ada dalam versi produksi, kode yang seharusnya berurusan dengan perilaku anggun akan diuji dengan buruk dan rusak sama buruknya dengan, jika tidak lebih buruk dari, kode itu seandainya tidak dijaga.
Sebastian Redl
0

Satu masalah dengan menegaskan bagi saya adalah bahwa mereka dinonaktifkan secara default di Jawa.

Kami menggunakan strategi gagal-pertama di mana program - yang mungkin telah berjalan tanpa pengawasan selama bertahun-tahun - harus macet sedini mungkin untuk menghindari korupsi data jika terjadi data yang buruk (pada formulir yang tidak terduga). Inilah yang kami gunakan untuk pemeriksaan, dan dengan menggunakan penegasan, kami pada dasarnya mengambil risiko mereka tidak aktif.


sumber