Saat memodelkan kelas, apa cara yang disukai untuk menginisialisasi:
- Konstruktor, atau
- Metode Pabrik
Dan apa pertimbangan untuk menggunakan keduanya?
Dalam situasi tertentu, saya lebih suka memiliki metode pabrik yang mengembalikan nol jika objek tidak dapat dibangun. Ini membuat kode rapi. Saya hanya dapat memeriksa apakah nilai yang dikembalikan tidak nol sebelum mengambil tindakan alternatif, berbeda dengan melemparkan pengecualian dari konstruktor. (Saya pribadi tidak suka pengecualian)
Katakanlah, saya memiliki konstruktor pada kelas yang mengharapkan nilai id. Konstruktor menggunakan nilai ini untuk mengisi kelas dari database. Dalam kasus di mana catatan dengan id yang ditentukan tidak ada, konstruktor melempar RecordNotFoundException. Dalam hal ini saya harus menyertakan konstruksi semua kelas tersebut dalam blok try..catch.
Berbeda dengan ini, saya dapat memiliki metode pabrik statis pada kelas-kelas yang akan mengembalikan nol jika catatan tidak ditemukan.
Pendekatan mana yang lebih baik dalam hal ini, konstruktor atau metode pabrik?
Tanyakan pada diri sendiri apa itu dan mengapa kita memilikinya. Mereka berdua ada di sana untuk membuat instance dari suatu objek.
Tidak ada perbedaan sejauh ini. Sekarang bayangkan bahwa kita memiliki berbagai jenis sekolah dan kita ingin beralih dari menggunakan ElementarySchool ke HighSchool (yang berasal dari ElementarySchool atau mengimplementasikan antarmuka ISchool yang sama dengan ElementarySchool). Perubahan kode adalah:
Dalam hal antarmuka kita memiliki:
Sekarang jika Anda memiliki kode ini di banyak tempat Anda dapat melihat bahwa menggunakan metode pabrik mungkin cukup murah karena setelah Anda mengubah metode pabrik Anda selesai (jika kita menggunakan contoh kedua dengan antarmuka).
Dan inilah perbedaan utama dan keunggulannya. Ketika Anda mulai berurusan dengan hierarki kelas yang kompleks dan Anda ingin secara dinamis membuat instance dari sebuah kelas dari hierarki tersebut, Anda mendapatkan kode berikut. Metode pabrik mungkin mengambil parameter yang memberi tahu metode tersebut contoh konkret yang akan dipakai. Katakanlah Anda memiliki kelas MyStudent dan Anda harus membuat instance objek ISchool yang sesuai sehingga siswa Anda adalah anggota sekolah itu.
Sekarang Anda memiliki satu tempat di aplikasi Anda yang berisi logika bisnis yang menentukan objek ISchool mana yang akan dipakai untuk berbagai objek IStudent yang berbeda.
Jadi - untuk kelas sederhana (objek nilai, dll.) Konstruktor baik-baik saja (Anda tidak ingin overengineer aplikasi Anda) tetapi untuk metode pabrik hierarki kelas yang kompleks adalah cara yang disukai.
Dengan cara ini Anda mengikuti prinsip desain pertama dari geng empat buku "Program ke antarmuka, bukan implementasi".
sumber
IFood sandwich = new Sandwich(Cheese chz, Meat meat);
danIFood soup = new Soup(Broth broth, Vegetable veg);
Bagaimana pabrik dan atau pembangun dapat membantu di sini?Anda perlu membaca (jika Anda memiliki akses ke) Java 2 Item 1: Pertimbangkan metode pabrik statis daripada konstruktor .
Metode pabrik statis keuntungan:
Kerugian metode pabrik statis:
sumber
( factory methods are better than Constructors. ( Item-1 ) ) Effective java
Secara default, konstruktor harus lebih disukai, karena mereka lebih mudah dimengerti dan ditulis. Namun, jika Anda secara khusus perlu memisahkan sifat konstruksi suatu objek dari makna semantiknya sebagaimana dipahami oleh kode klien, Anda sebaiknya menggunakan pabrik.
Perbedaan antara konstruktor dan pabrik adalah analog dengan, katakanlah, variabel dan pointer ke variabel. Ada tingkat tipuan lain, yang merupakan kerugian; tetapi ada tingkat fleksibilitas lain juga, yang merupakan keuntungan. Jadi saat membuat pilihan, Anda sebaiknya disarankan melakukan analisis biaya versus manfaat ini.
sumber
Gunakan pabrik hanya ketika Anda membutuhkan kontrol ekstra dengan pembuatan objek, dengan cara yang tidak dapat dilakukan dengan konstruktor.
Pabrik memiliki kemungkinan caching misalnya.
Cara lain untuk menggunakan pabrik adalah dalam skenario di mana Anda tidak tahu jenis yang ingin Anda bangun. Seringkali Anda melihat jenis penggunaan ini dalam skenario pabrik plugin, di mana setiap plugin harus berasal dari baseclass atau mengimplementasikan beberapa jenis antarmuka. Pabrik membuat instance kelas yang berasal dari baseclass atau yang mengimplementasikan antarmuka.
sumber
Sebuah kutipan dari "Java Efektif", edisi ke-2, Butir 1: Pertimbangkan metode pabrik statis alih-alih konstruktor, hal. 5:
"Perhatikan bahwa metode pabrik statis tidak sama dengan pola Metode Pabrik dari Pola Desain [Gamma95, hal. 107]. Metode pabrik statis yang dijelaskan dalam item ini tidak memiliki padanan langsung dalam Pola Desain."
sumber
Selain "java efektif" (seperti yang disebutkan dalam jawaban lain), buku klasik lain juga menyarankan:
Misalnya. jangan menulis
melainkan menulis
Buku ini sejauh menyarankan untuk membuat
Complex(float)
konstruktor pribadi, untuk memaksa pengguna untuk memanggil metode pabrik statis.sumber
from…
,to…
,parse…
,with…
, dan sebagainya. Perlu diingat bahwa kelas java.time dibangun agar tidak berubah, tetapi beberapa konvensi penamaan ini mungkin berguna untuk diikuti dengan kelas yang bisa berubah juga.Contoh nyata dari aplikasi CAD / CAM.
Jalur pemotongan akan dibuat dengan menggunakan konstruktor. Ini adalah serangkaian garis dan busur yang mendefinisikan jalur untuk memotong. Sementara rangkaian garis dan busur dapat berbeda dan memiliki koordinat yang berbeda dengan mudah ditangani dengan meneruskan daftar ke konstruktor.
Suatu bentuk akan dibuat dengan menggunakan pabrik. Karena meskipun ada kelas bentuk, setiap bentuk akan diatur berbeda tergantung pada jenis bentuknya. Kami tidak tahu bentuk apa yang akan kami inisialisasi hingga pengguna membuat pilihan.
sumber
Proses ini tentunya harus di luar konstruktor.
Konstruktor tidak boleh mengakses database.
Tugas dan alasan konstruktor adalah menginisialisasi anggota data dan menetapkan kelas invarian menggunakan nilai yang diteruskan ke konstruktor.
Untuk yang lainnya pendekatan yang lebih baik adalah menggunakan metode pabrik statis atau dalam kasus yang lebih kompleks kelas pabrik atau pembangun yang terpisah .
Beberapa garis panduan konstruktor dari Microsoft :
Dan
sumber
Terkadang Anda harus memeriksa / menghitung beberapa nilai / kondisi saat membuat objek. Dan jika itu dapat membuang Exception - constructro adalah cara yang sangat buruk. Jadi, Anda perlu melakukan sesuatu seperti ini:
Di mana semua perhitungan tambahan ada di init (). Tetapi hanya Anda sebagai pengembang yang benar-benar tahu tentang init ini (). Dan tentu saja, setelah berbulan-bulan Anda hanya melupakannya. Tetapi jika Anda memiliki pabrik - cukup lakukan semua yang Anda perlukan dalam satu metode dengan menyembunyikan init ini () dari panggilan langsung - jadi tidak ada masalah. Dengan pendekatan ini tidak ada masalah dengan jatuh pada penciptaan dan kebocoran memori.
Seseorang memberi tahu Anda tentang caching. Ini baik. Tetapi Anda juga harus ingat tentang pola Flyweight yang bagus untuk digunakan dengan cara Factory.
sumber