Jadi saya punya pabrik yang membuat objek dari berbagai kelas. Semua kelas yang mungkin berasal dari nenek moyang abstrak. Pabrik memiliki file konfigurasi (sintaks JSON) dan memutuskan kelas mana yang akan dibuat, tergantung pada konfigurasi pengguna.
Untuk mencapai ini, pabrik menggunakan boost :: property_tree untuk penguraian JSON. Dia berjalan melalui ptree dan memutuskan objek konkret yang akan dibuat.
Namun, objek produk memiliki banyak bidang (atribut). Bergantung pada kelas konkret, objek memiliki sekitar 5-10 atribut, di masa depan mungkin bahkan lebih.
Jadi saya tidak yakin bagaimana seharusnya konstruktor dari objek tersebut. Saya dapat memikirkan dua solusi:
1) Konstruktor produk mengharapkan setiap atribut sebagai parameter, dengan demikian, konstruktor tersebut akan berakhir dengan 10+ parameter. Ini akan menjadi jelek dan mengarah pada baris kode yang panjang dan tidak dapat dibaca. Namun, keuntungannya adalah bahwa pabrik dapat mengurai JSON dan memanggil konstruktor dengan parameter yang benar. Kelas produk tidak perlu tahu bahwa itu telah dibuat karena konfigurasi JSON. Tidak perlu tahu ada JSON atau konfigurasi yang terlibat sama sekali.
2) Konstruktor produk hanya mengharapkan satu argumen, objek property_tree. Maka dapat mem-parsing informasi yang dibutuhkan. Jika ada informasi dalam konfigurasi yang hilang atau di luar batas, setiap kelas produk dapat bereaksi dengan benar. Pabrik tidak perlu tahu argumen apa yang dibutuhkan oleh beberapa produk. Pabrik juga tidak perlu tahu bagaimana harus bereaksi jika konfigurasi salah. Dan antarmuka konstruktor bersatu dan kecil. Tetapi, sebagai kerugian, produk perlu mengekstraksi informasi yang diperlukan dari JSON, sehingga, ia tahu bagaimana itu dibangun.
Saya cenderung lebih suka solusi 2). Namun, saya tidak yakin apakah ini pola pabrik yang baik. Entah bagaimana rasanya membiarkan produk tahu bahwa itu dibuat dengan konfigurasi JSON. Di sisi lain, produk baru dapat diperkenalkan dengan sangat sederhana.
Ada pendapat tentang itu?
Jawaban:
Saya tidak akan melakukan opsi 2, karena dengan begitu Anda telah selamanya melilit konstruksi objek Anda dengan meningkatkan parsing pohon properti. Jika Anda nyaman dengan kelas yang membutuhkan banyak parameter, Anda harus merasa nyaman dengan konstruktor yang membutuhkan banyak parameter, seperti hidup!
Jika masalah utama Anda adalah keterbacaan kode, Anda dapat menggunakan pola builder, itu pada dasarnya adalah c ++ / java sementara karena kurangnya argumen bernama. Anda berakhir dengan hal-hal yang terlihat seperti ini:
Jadi sekarang MyObject akan memiliki konstruktor pribadi, yang dipanggil di Builder :: build. Yang menyenangkan adalah bahwa itu akan menjadi satu-satunya tempat Anda pernah memanggil konstruktor dengan 10 parameter. Pabrik tree properti boost akan menggunakan builder, dan selanjutnya jika Anda ingin membangun MyObject secara langsung atau dari sumber yang berbeda, Anda akan melalui builder. Dan pembangun pada dasarnya memungkinkan Anda memberi nama setiap parameter dengan jelas saat Anda meneruskannya, sehingga lebih mudah dibaca. Ini jelas menambahkan beberapa boilerplate, jadi Anda harus memutuskan apakah itu layak dibandingkan dengan hanya memanggil konstruktor yang berantakan, atau menyatukan beberapa parameter Anda yang ada ke dalam struct, dll. Hanya melemparkan opsi lain di atas meja.
https://en.wikipedia.org/wiki/Builder_pattern#C.2B.2B_Example
sumber
JANGAN gunakan pendekatan kedua.
Ini jelas bukan solusi dan hanya akan mengarah pada instantiating kelas dalam logika bisnis Anda, bukan bagian dari aplikasi Anda di mana pabrik berada.
Antara:
Kecuali objek yang Anda buat sebenarnya adalah kelas yang bertanggung jawab untuk menyimpan data, Anda harus mencoba untuk memperbaiki kode dan membagi kelas besar menjadi yang lebih kecil.
sumber
new
atau membuat objek di dalam logika bisnis Anda, itu bukan desain yang sangat bagus. Periksa Pembicaraan jangan mencari hal-hal oleh Miško Hevery , yang menjelaskan secara lebih mendalam mengapa pendekatan pabrik yang Anda isyaratkan buruk dari sudut pandang pengujian dan membaca. Juga, kelas Anda tampaknya menjadi objek data, dan bagi mereka umumnya boleh saja memiliki lebih banyak parameter daripada kelas layanan reguler. Saya tidak akan terlalu terganggu.Opsi 2 hampir benar.
Opsi yang ditingkatkan 2
Buat kelas "menghadap ke depan" yang tugasnya adalah untuk mengambil objek struktur JSON dan memilih bit dan memanggil konstruktor pabrik. Dibutuhkan apa yang pabrik buat dan berikan ke klien.
Pada dasarnya "ujung depan" mengatakan kepada 2 Bob: "Saya berurusan dengan pelanggan yang telah dihapus sehingga para insinyur tidak perlu melakukannya! Saya memiliki keterampilan orang-orang!" Tom yang malang. Jika dia hanya mengatakan, "Saya memisahkan klien dari konstruksi. Hasil ini adalah pabrik yang sangat kohesif"; dia mungkin mempertahankan pekerjaannya.
Terlalu Banyak Argumen?
Bukan untuk klien - komunikasi ujung depan.
Front end - pabrik? Jika tidak 10 parameter maka yang terbaik yang dapat Anda lakukan adalah menunda membongkar, jika bukan JSON asli maka beberapa DTO. Apakah ini lebih baik daripada melewatkan JSON ke pabrik? Perbedaan yang sama saya katakan.
Saya akan sangat mempertimbangkan melewati parameter individual. Tetap berpegang pada tujuan pabrik yang bersih dan kohesif. Hindari kekhawatiran jawaban @DavidPacker.
Mengurangi "terlalu banyak argumen"
Konstruktor pabrik atau kelas
Pengelompokan argumen front end
sumber