Bersihkan validasi arsitektur di lapisan persistensi domain vs data?

13

Saya belajar di bersih dan sebagai hasilnya saya secara dramatis memikirkan kembali banyak cara saya merancang dan menulis perangkat lunak.

Namun saya masih bergumul dengan aturan bisnis seperti "simpan pembaruan untuk beberapa item, muat pertama Semua daftar item yang saya miliki izin untuk melihat / mengedit dll, mengkonfirmasi bahwa item ini ada dalam daftar, dan bahwa kategori item saat ini tidak dikunci dari penggunaan, (dan aturan lainnya, dll, dll) ".. karena itu adalah aturan bisnis (kompleks tetapi tidak atipikal), dan karenanya harus ditangani dalam domain aplikasi daripada mendorong logika bisnis ke dalam lapisan db / kegigihan.

Namun bagi saya tampaknya untuk secara efisien memeriksa kondisi ini sering kali akan lebih baik ditangani dengan permintaan db yang dibuat dengan baik, daripada memuat semua data ke dalam domain aplikasi ...

Tanpa optimasi prematur, apa pendekatan yang disarankan atau beberapa artikel paman Bob yang berurusan dengan pertanyaan ini? Atau akankah dia mengatakan "validasi dalam domain sampai menjadi masalah" ??

Saya benar-benar berjuang untuk menemukan contoh / sampel yang bagus untuk apa pun selain yang paling dasar dari kasus penggunaan.

Memperbarui:

Hai semua, terima kasih atas balasannya. Seharusnya saya lebih jelas, saya telah menulis perangkat lunak (kebanyakan aplikasi web) untuk waktu yang lama, dan sudah pasti sudah berpengalaman dan setuju dengan semua topik yang Anda uraikan secara kolektif (validasi dengan backend, jangan percaya data klien, secara umum kejar efisiensi mentah hanya jika diperlukan, namun akui kekuatan alat db saat tersedia, dll.) dan telah melalui siklus pembelajaran pengembang "membuang semuanya" untuk "membangun pengendali lemak raksasa dengan aplikasi N-tiers" tren kode , dan sekarang benar-benar menyukai dan menyelidiki gaya bersih / tanggung jawab tunggal dll, pada dasarnya sebagai hasil dari beberapa proyek baru-baru ini yang berkembang menjadi aturan bisnis yang cukup kikuk dan didistribusikan secara luas seiring proyek berkembang dan kebutuhan klien lebih lanjut terungkap.

Secara khusus, saya melihat arsitektur gaya bersih dalam konteks membangun REST apis untuk menghadapi klien serta fungsionalitas penggunaan internal, di mana banyak aturan bisnis mungkin jauh lebih kompleks daripada pada dasarnya setiap contoh yang Anda lihat di internet (Bahkan oleh arsitektur Clean / Hex guys sendiri).

Jadi saya kira saya benar-benar bertanya (dan gagal menyatakan dengan jelas) tentang bagaimana Bersih dan api REST akan duduk bersama, di mana sebagian besar barang MVC yang Anda lihat hari ini memiliki validator permintaan yang masuk (mis. Perpustakaan FluentValidation di .NET), tetapi di mana banyak aturan "validasi" saya tidak terlalu banyak "apakah ini string kurang dari 50 karakter" tetapi lebih "dapatkah pengguna ini memanggil usercase / interaksor ini melakukan operasi ini pada kumpulan data ini mengingat bahwa beberapa objek terkait saat ini dikunci oleh Tim X sampai akhir bulan dll dll "... validasi semacam itu sangat terlibat di mana BANYAK objek domain bisnis dan aturan domain berlaku.

Haruskah saya mengubah aturan-aturan itu menjadi jenis tertentu dari tipe objek Validator untuk menemani setiap pengguna-interaksi (terinspirasi oleh proyek FluentValidator tetapi dengan lebih banyak logika bisnis dan akses data yang terlibat), haruskah saya memperlakukan validasi seperti Gateway, haruskah saya letakkan validasi tersebut DI gateway (yang saya pikir salah), dll.

Sebagai referensi, saya pergi beberapa artikel seperti ini , tetapi Mattia tidak banyak membahas validasi.

Tapi saya kira jawaban singkat untuk pertanyaan saya mirip dengan jawaban yang saya terima: "Tidak pernah mudah, dan itu tergantung".

Dale Holborow
sumber
2
Sering ada perbedaan antara menjadi "benar" dan menjadi "praktis." Diberi pilihan, mana yang Anda sukai?
Robert Harvey
"memuat Semua daftar item" tidak terlihat seperti aturan bisnis, sepertinya terlalu banyak membahas rincian implementasi. Jika Anda dapat memenuhi aturan dengan menggunakan permintaan db, tanpa memuat apa pun, mengapa aturan mengatakan "memuat"?
Berhentilah melukai Monica

Jawaban:

31

Validasi entri data adalah salah satu hal di mana semua orang mulai berusaha membuatnya murni dan bersih dan (jika mereka pintar tentang hal itu) akhirnya menyerah, karena ada begitu banyak masalah yang saling bersaing.

  • Lapisan UI harus melakukan beberapa bentuk validasi di sana pada halaman / formulir klien untuk memberikan umpan balik realtime kepada pengguna. Kalau tidak, pengguna menghabiskan banyak waktu menunggu umpan balik sementara transaksi posting di jaringan.

  • Karena klien sering berjalan pada mesin yang tidak terpercaya (mis. Di hampir semua aplikasi web), rutinitas validasi ini harus dijalankan lagi di sisi server tempat kode dipercaya.

  • Beberapa bentuk validasi implisit karena kendala input; misalnya, kotak teks hanya memungkinkan entri numerik. Ini berarti bahwa Anda mungkin tidak memiliki "apakah ini numerik?" validator pada halaman, tetapi Anda masih perlu satu di bagian belakang, di suatu tempat, karena kendala UI dapat dilewati (misalnya dengan menonaktifkan Javascript).

  • Lapisan UI harus melakukan beberapa bentuk validasi pada batas layanan (misalnya kode sisi server dalam aplikasi web) untuk melindungi sistem terhadap serangan injeksi atau bentuk entri data berbahaya lainnya. Terkadang validasi ini bahkan tidak ada dalam basis kode Anda, mis . Validasi permintaan ASP.NET .

  • Lapisan UI harus melakukan beberapa bentuk validasi hanya untuk mengubah data yang dimasukkan pengguna ke dalam format yang dapat dipahami oleh lapisan bisnis; misalnya, harus mengubah string "6/26/2017" menjadi objek DateTime di zona waktu yang sesuai.

  • Lapisan bisnis harus melakukan sebagian besar bentuk validasi karena, hei, mereka termasuk dalam lapisan bisnis, secara teori.

  • Beberapa bentuk validasi lebih efisien pada lapisan basis data, terutama ketika pemeriksaan integritas referensial diperlukan (misalnya untuk memastikan bahwa kode status ada dalam daftar 50 negara yang valid).

  • Beberapa bentuk validasi harus terjadi dalam konteks transaksi basis data karena masalah konkurensi, misalnya pemesanan nama pengguna yang unik harus bersifat atomik sehingga beberapa pengguna lain tidak mengambilnya saat Anda sedang memproses.

  • Beberapa bentuk validasi hanya dapat dilakukan oleh layanan pihak ketiga, misalnya ketika memvalidasi bahwa kode pos dan nama kota digabungkan.

  • Di seluruh sistem, pemeriksaan nol dan pemeriksaan konversi data dapat terjadi di beberapa lapisan, untuk memastikan mode kegagalan yang wajar di hadapan kelemahan kode.

Saya telah melihat beberapa pengembang mencoba untuk mengodifikasi semua aturan validasi di lapisan bisnis, dan kemudian meminta lapisan lain untuk mengekstrak aturan bisnis dan merekonstruksi validasi pada lapisan yang berbeda. Secara teori ini akan bagus karena Anda berakhir dengan satu sumber kebenaran. Tetapi saya belum pernah melihat pendekatan ini melakukan apa pun selain menyulitkan solusi, dan seringkali berakhir dengan sangat buruk.

Jadi, jika Anda bunuh diri mencoba mencari tahu ke mana kode validasi Anda pergi, maklumi-- dalam solusi praktis untuk masalah yang bahkan cukup kompleks, kode validasi akan berakhir di beberapa tempat.

John Wu
sumber
Jika Anda menganggap bahwa Anda UI yang mengelola semua umpan balik pengguna, Anda bisa mendorong sebagian besar pemeriksaan validasi dalam basis data dan hanya menyimpan apa yang tidak dapat Anda lakukan di dalamnya di lapisan bisnis. Masalah muncul jika Anda merancang API backend penuh dengan pemecahan masalah pesan yang sangat rinci.
Walfrat
2

Validasi adalah bagian dari lapisan bisnis.

Intinya adalah: logika bisnis dalam DAO akan membatalkan konsep DAO. Untuk melakukan validasi di lapisan yang lebih tinggi akan menghasilkan validasi yang berlebihan jika Anda memanggil operasi bisnis dari usecase lain.

Mungkin Anda mengevaluasi beberapa keamanan di UI. Tapi itu opsional karena objek domain aman akan melakukan pekerjaan penting. Di UI akan membuat Komponen terlihat atau tidak terlihat tergantung pada izin yang dimiliki pengguna yang masuk saat ini. Tapi ini hanya bagian dari pengalaman pengguna. Anda tidak ingin pengguna membiarkannya menjadi pengecualian keamanan setiap kali ia mencoba melakukan tindakan yang tidak diizinkan.

oopexpert
sumber
2

Anda mungkin ingin memeriksa perspektif Anda tentang siapa yang melakukan validasi vis-à-vis. Apakah itu DB, di mana Anda tahu Anda bekerja dengan DB? Atau itu layanan (yang didukung dan dikendalikan oleh operasi DB). Pada proyek saya, setiap agregat root memiliki daftar grup yang dapat membacanya dan daftar pengubah. Ketika kode mencari root tertentu atau daftar root yang dapat dilihat pengguna, semua detail disembunyikan di balik layanan yang mengambil id pengguna dan bagian tambahan konteks pencarian seperti di mana ubin dimulai dengan "bla". Kode tidak peduli bahwa DB melakukan pemeriksaan yang ada untuk melihat apakah grup pengguna ada di grup pembaca. Itu hanya mengharapkan daftar dengan atau tanpa konten berdasarkan apa yang disediakan oleh layanan, yang hanya ditentukan oleh kontrak.

Ini berlaku di semua lapisan. Keseragaman validasi adalah kuncinya. Masukkan sebanyak mungkin validasi Anda ke domain. Kembalikan kendala dengan api Anda. Saya akhirnya tidak memikirkan kendala yang datang dari perpustakaan X atau penyimpanan Z, tetapi dari layanan.

Virmundi
sumber
0

Jika beberapa logika validasi dinyatakan paling sederhana dan paling jelas dalam bentuk kueri basis data, maka silakan, Anda memiliki jawaban Anda. Tetapi efisiensi seharusnya hanya menjadi perhatian jika Anda memiliki masalah kinerja yang diketahui, jika tidak itu adalah optimasi prematur.

JacquesB
sumber