Mewakili aturan bisnis dengan pengecualian

16

Saya tahu itu mahal tapi (IMO) saya percaya ini adalah praktik yang sangat bagus. Saya sedang berbicara tentang aturan seperti katakan, Anda tidak dapat menyimpan Faktur jika Anda bukan orang penjualan ... jadi dalam hal itu melemparkan pengecualian yang mengatakan 'Anda tidak berwenang' atau semacamnya ...

Pendekatan lain akan memiliki objek dengan status atau sesuatu seperti itu

Apakah ada pendekatan lain? bagaimana perasaanmu tentang itu?

sebagomez
sumber

Jawaban:

15

Jika Anda bermaksud mewakili pengecekan aturan bisnis individu dengan pengecualian, maka menurut saya itu bukan ide yang bagus. Sering kali Anda harus melaporkan lebih dari satu kondisi gagal, dan tidak berhenti pada yang pertama.

Di sisi lain, saya percaya bahwa memeriksa semua aturan dan kemudian melemparkan pengecualian dengan ringkasan adalah praktik yang baik.

matiash
sumber
1
Itulah tepatnya bagaimana saya menanganinya di aplikasi saya. Menggunakan FluentValidation untuk membuat hidup saya mudah, dan metode ValidateAndThrow menghemat hari saya.
Matteo Mosca
Dalam aplikasi UI saya sepenuhnya setuju, tetapi dalam aplikasi tingkat layanan saya akan menghasilkan pengecualian jika saya melewati objek yang tidak mematuhi aturan bisnis. Jika Anda menggunakan keduanya dalam kombinasi maka kadang-kadang Anda dan ke atas menambahkan fungsi validasi atau kesalahan kompleks seperti yang dijelaskan matiasha dalam kalimat terakhir.
Bill
8
Lempar pengecualian khusus domain . Ini memungkinkan Anda untuk memisahkan antara milik kita dan milik kita di atas.
@ Thorbjørn Ravn Andersen +1 "khusus domain" tambahan
Justin Ohms
1
@JamesPoulson mungkin cukup untuk membuat JamesPoulsonExceptionsebagai subkelas RuntimeExceptiondan kemudian memberikan pengecualian asli sebagai cause. Kemudian Anda bisa mengatakan if (exception instanceof JamesPoulsonException)... membedakan. Gunakan getCause()metode untuk mencapai pengecualian asli.
9

Dalam contoh yang Anda berikan kepada kami, saya pikir mengajukan pengecualian adalah ide yang buruk. Jika Anda tahu bahwa pengguna tidak diotorisasi sebelum mereka mulai bekerja dan Anda masih mengizinkan mereka untuk melakukan beberapa fungsi dan kemudian memukul mereka dengan pesan SETELAH mereka telah menyelesaikan tugas, itu hanya desain yang buruk.

Menggunakan pengecualian untuk menegakkan aturan bisnis bukanlah desain yang baik.

Walter
sumber
Yang saya mengerti dari apa yang Anda katakan, adalah bahwa Anda tidak setuju dengan UI. Saya setuju dengan itu. Saya setuju dengan Anda bahwa UI yang jauh lebih ramah tidak akan membiarkan Anda mencoba memperbarui sesuatu yang tidak diizinkan. Tetapi itu tidak berarti bahwa pemeriksaan validasi dan pengecualian di inti bisnis tidak perlu. Sebaliknya, saya percaya mereka adalah suatu keharusan. Anda membutuhkan mereka untuk memastikan bahwa UI yang diprogram dengan buruk tidak mengizinkan penyalahgunaan BL.
Fede
8
@Fede: ini adalah pertanyaan tentang pemisahan masalah. UI bertanggung jawab untuk mengumpulkan niat pengguna dan melaporkan umpan balik dari lapisan bisnis. Pekerjaan lapisan bisnis adalah menganalisis informasi yang dikumpulkan oleh UI, menganalisisnya dan melaporkan kembali ke UI dan / atau meminta lapisan data untuk mempertahankan beberapa data. Seharusnya hanya ada kopling longgar antara lapisan-lapisan ini. Pengecualian adalah pendekatan yang buruk dan buruk untuk lepas-gabungkan. Tidak hanya berarti berbagi kelas aktual antar lapisan tetapi juga meminta mekanisme yang dimaksudkan untuk menangani kegagalan yang tidak terduga.
Adam Crossland
@ Adam - Kata baik dan tepat pada poin.
Walter
1
@Adam - Jangan ikuti Anda dengan pemisahan masalah yang menjadi perhatian. Saya tidak mengharapkan siapa pun di UI untuk menangani CustomerNameInLowercaseException (tolong, saya juga berharap pengecualian itu bahkan tidak ada!). Anda bisa menangani ValidationException umum. Selain itu, saya 100% bersama Anda bahwa UI hanya mengumpulkan informasi, dan semua itu. Apa yang saya katakan sebelumnya adalah bahwa apa pun yang Anda lakukan di UI, BL tidak boleh berasumsi bahwa setiap input ok. Ini hanya beberapa program defensif.
Fede
@Fede: itu adalah tugas Layer Bisnis untuk memastikan bahwa setiap input OK. Jika UI melakukannya maka ia menerapkan logika bisnis. Sekarang, jika itu adalah kasus bahwa field input dibatasi untuk angka dan BL yang melihat alpha karakter, dengan semua cara melemparkan sebuah pengecualian . Setiap kali komponen menerima input yang tidak valid dari komponen lain, melemparkan pengecualian adalah logis dan benar. Antarmuka telah rusak, dan sistem rusak. Namun, memvalidasi input sangat berbeda dari mengeksekusi logika bisnis. Dua hal yang sangat berbeda.
Adam Crossland
5

Saya tidak melihat nilai apa yang dimiliki oleh Pengecualian dalam menciptakan logika bisnis yang baik. Ada banyak pendekatan untuk menangani logika bisnis yang tidak melibatkan penggunaan sistem yang dimaksudkan untuk mengatasi kondisi yang tidak terduga dalam pengoperasian sistem.

Hal ini diharapkan bahwa dalam logika bisnis, kondisi akan tidak dipenuhi; itulah alasan untuk memilikinya di tempat pertama, dan Anda tidak ingin membonceng mekanisme yang sama yang menangani kegagalan I / O yang tak terduga, dari kesalahan memori dan referensi nol. Itu adalah kegagalan sistem, tetapi mendeteksi kondisi bisnis yang tidak terpenuhi adalah keberhasilan operasi sistem.

Selain itu, ini adalah sistem yang matang untuk konsekuensi yang tidak diinginkan. Karena suatu pengecualian harus ditangkap pada titik tertentu, Anda berisiko mengambil pengecualian aturan bisnis baru yang tertangkap di suatu tempat yang tidak dimaksudkan atau Anda berkesempatan memiliki kode yang mencari aturan bisnis yang menangkap pengecualian yang sebenarnya tidak dimaksudkan untuk itu. Ya, kondisi ini dapat diperhitungkan dengan praktik pengkodean yang baik, tetapi dalam sistem non-sepele di mana lebih dari satu pengembang bekerja, kesalahan akan terjadi, dan Anda hanya harus berharap bahwa itu tidak akan menjadi kesalahan mahal.

Adam Crossland
sumber
1
Saya setuju, pengecualian disebut pengecualian karena mereka tidak diharapkan terjadi. Di sisi lain, menegakkan aturan bisnis di tingkat layanan Anda dengan pengecualian tidak selalu salah. Anda tidak mengharapkannya digunakan, Anda berharap klien hanya menjalankan operasi dan hanya mengirimkan data yang memenuhi persyaratan yang valid; tetapi Anda ingin membangun lapisan perlindungan karena Anda tahu kesalahan dapat terjadi pada pengkodean klien juga. Agak seperti menggunakan batasan kunci asing dalam database: Anda mengharapkan orang memasukkan dan memperbarui data dengan benar tetapi tahu mereka bisa gagal karena kesalahan pemrograman.
Jeremy
2

mengungkapkan aturan bisnis adalah satu hal, menerapkannya adalah hal lain

pikirkan tentang pengalaman pengguna; jika pengguna bukan tenaga penjualan, mengapa memberi mereka tombol yang mengatakan 'buat faktur' sama sekali ?

Steven A. Lowe
sumber
1
Hanya karena Anda tidak memberikan tombol, itu tidak berarti mereka tidak akan mengirimi Anda pesan untuk melakukan sesuatu. Pikirkan betapa mudahnya aturan keamanan jika hanya itu yang diperlukan ..
jmoreno
Jika pengguna tidak diizinkan melakukan X, jangan beri mereka tombol yang mengatakan "Lakukan X". Keamanan terbaik adalah ketidaktahuan - jangan beri tahu pengguna tentang hal-hal yang tidak dapat mereka lakukan;)
Steven A. Lowe
1

Itu sepenuhnya tergantung pada apa yang sedang dilakukan.

Pertama, apa perilaku aktual yang Anda inginkan? Jika seseorang memasukkan informasi mereka sendiri, maka penolakan dan kotak dialog yang mengatakan, pada dasarnya, "Anda tidak bisa melakukan itu" mungkin benar. Jika ini adalah orang entri data, bekerja dari tumpukan formulir, kotak dialog mungkin juga bagus, dan orang entri data dapat meletakkan formulir yang tidak valid di tumpukan khusus. Jika Anda melakukan pemrosesan batch, Anda tidak ingin menghentikan semuanya, tetapi beri tanda dan pindah ke yang berikutnya.

Setelah Anda memiliki perilaku, Anda perlu memutuskan bagaimana Anda akan menerapkannya. Memiliki pemeriksa aturan bisnis yang melempar pengecualian mungkin merupakan ide yang bagus. Mengembalikan kode pengembalian dan meneruskannya adalah hal lain yang bisa salah, dan Anda tentu tidak ingin entri yang salah semakin jauh.

Jangan khawatir tentang biaya kinerja. Dalam hal seseorang memasukkan data, itu sepele dibandingkan dengan waktu lain yang terlibat. Biasanya, manusia akan mengambil waktu paling banyak dalam sistem itu. Dalam kasus pekerjaan batch, jika pengecualian adalah masalah kinerja, Anda memasukkan terlalu banyak catatan buruk, dan dalam kenyataannya menangani dan memasukkan kembali semua itu akan menjadi lebih banyak masalah daripada pengecualian.

David Thornley
sumber
0

Memiliki API pengecualian yang kuat dan dirancang dengan baik yang konsisten sangat tepat. Menggunakan ini untuk menegakkan aturan bisnis juga bisa sesuai. Bahkan dalam pengalaman saya, semakin rumit aturan bisnis, semakin besar kemungkinannya akan ditangani dengan cara ini. Seringkali sama mudahnya jika tidak lebih mudah untuk menulis suatu sistem di mana pengecualian diharapkan daripada menulis logika percabangan yang otoritatif.

Ini untuk mengatakan bahwa aturan sederhana yang dapat dijelaskan dalam satu kalimat pada umumnya harus dilaksanakan dengan cara preventif atau otoritatif tergantung pada mana itu. Namun, jika Anda memiliki aturan yang multi-dimensi dan memerlukan lebih dari tiga atau empat faktor (terutama jika pemilihan faktor-faktor ini didasarkan pada satu atau lebih dari faktor-faktor lain) maka pengkodean pengecualian mungkin lebih dapat dipertahankan. Seringkali dalam kasus ini jalur logika akan memiliki banyak pengecualian prekursor yang perlu dilempar, (memeriksa mengapa tindakan tidak dapat dilakukan) kemudian (atau sebaliknya) ada kejatuhan ke keamanan (untuk memeriksa bahwa tindakan itu diotorisasi ), kadang-kadang akan ada beberapa logika akumulasi otoritatif yang perlu diperiksa (ketersediaan keturunan / leluhur, prekursor menyatakan bahwa objek harus dimasukkan ke dalam, dll.

Salah satu manfaat yang diperoleh dari jenis lemparan pengecualian ini adalah Anda dapat memisahkan dan menggunakan kembali pengecualian prekursor di berbagai area proyek Anda. (Ini adalah inti dari Pemrograman Berorientasi Aspek.) Dengan melakukan ini Anda merangkum satu aspek tertentu dari aturan bisnis umum Anda dalam komponen mandiri dan dapat dikelola. Secara umum komponen ini akan sesuai 1-1 dengan pesan kesalahan yang dilemparkan. (Meskipun kadang-kadang Anda akan memiliki satu komponen yang melempar beberapa pengecualian berbeda, Anda seharusnya hampir tidak pernah memiliki pengecualian yang sama dilemparkan dari beberapa komponen.)

Menurut pendapat saya, lebih sulit untuk merancang sistem yang berbasis pengecualian dan waktu pengembangan awal lebih lama karena Anda harus membangun proses pengecualian di semua level N. Namun sistem ini pada akhirnya menjadi jauh lebih stabil. Meskipun tidak pernah mungkin untuk merancang sistem yang 'tidak akan gagal', manfaat dari desain berbasis pengecualian adalah bahwa Anda selalu mengantisipasi kegagalan. Bagi kebanyakan orang, prosesnya bisa kontra-intuitif. Ini seperti menanyakan arah dan meminta seseorang memberi tahu Anda semua jalan yang seharusnya tidak Anda nyalakan.

Justin Ohms
sumber