Mari kita lihat opsi, di mana kita dapat menempatkan kode validasi:
- Di dalam setter dalam pembangun.
- Di dalam
build()
metode.
- Di dalam entitas yang dibangun: itu akan dipanggil dalam
build()
metode ketika entitas sedang dibuat.
Opsi 1 memungkinkan kita untuk mendeteksi masalah sebelumnya, tetapi ada kasus rumit ketika kita dapat memvalidasi input hanya memiliki konteks penuh, dengan demikian, melakukan setidaknya sebagian dari validasi dalam build()
metode. Dengan demikian, memilih opsi 1 akan menyebabkan kode tidak konsisten dengan bagian validasi dilakukan di satu tempat dan bagian lain dilakukan di tempat lain.
Opsi 2 tidak jauh lebih buruk daripada opsi 1, karena, biasanya, seter dalam builder dipanggil tepat sebelum build()
, terutama, pada antarmuka yang lancar. Dengan demikian, masih mungkin untuk mendeteksi masalah cukup awal dalam kebanyakan kasus. Namun, jika pembuat bukan satu-satunya cara untuk membuat objek, itu akan mengarah pada duplikasi kode validasi, karena Anda harus memilikinya di mana pun Anda membuat objek. Solusi paling logis dalam hal ini adalah menempatkan validasi sedekat mungkin ke objek yang dibuat, yaitu di dalamnya. Dan ini adalah opsi 3 .
Dari sudut pandang SOLID, menempatkan validasi dalam builder juga melanggar SRP: kelas builder sudah memiliki tanggung jawab untuk menggabungkan data untuk membangun objek. Validasi adalah membuat kontrak dengan keadaan internal sendiri, itu adalah tanggung jawab baru untuk memeriksa keadaan objek lain.
Jadi, dari sudut pandang saya, tidak hanya lebih baik gagal terlambat dari perspektif desain, tetapi juga lebih baik gagal di dalam entitas yang dibangun, daripada di builder itu sendiri.
UPD: komentar ini mengingatkan saya pada satu kemungkinan lagi, ketika validasi di dalam builder (opsi 1 atau 2) masuk akal. Masuk akal jika pembangun memiliki kontrak sendiri pada objek yang dibuatnya. Sebagai contoh, asumsikan bahwa kita memiliki pembangun yang membangun string dengan konten spesifik, katakanlah, daftar rentang angka 1-2,3-4,5-6
. Pembangun ini mungkin memiliki metode seperti addRange(int min, int max)
. String yang dihasilkan tidak tahu apa-apa tentang angka-angka ini, tidak juga harus tahu. Pembangun itu sendiri mendefinisikan format string dan batasan pada angka. Dengan demikian, metode addRange(int,int)
harus memvalidasi angka input dan melemparkan pengecualian jika maks kurang dari min.
Yang mengatakan, aturan umum akan memvalidasi hanya kontrak yang ditentukan oleh pembangun itu sendiri.