Dalam paket java.time baru kelas inti menggunakan metode pabrik of
bukan konstruktor publik. Meskipun saya suka kosmetik of
metode ini, saya tidak bisa melihat alasan yang bagus untuk tidak menggunakan konstruktor. Dokumentasi yang saya temukan hanya menjelaskan bahwa ini adalah masalahnya dan tidak benar-benar menjelaskan mengapa itu terjadi.
Kutipan dari tutorial :
Sebagian besar kelas di Date-Time API membuat objek yang tidak dapat diubah, yang berarti bahwa, setelah objek dibuat, itu tidak dapat dimodifikasi. Untuk mengubah nilai objek yang tidak dapat diubah, objek baru harus dikonstruksi sebagai salinan asli dari yang asli. Ini juga berarti bahwa Date-Time API, menurut definisi, aman-utas. Ini memengaruhi API karena sebagian besar metode yang digunakan untuk membuat objek tanggal atau waktu diawali dengan, dari, atau dengan, bukan konstruktor, dan tidak ada metode yang ditetapkan.
Tidak selalu diperlukan untuk membuat objek baru saat mendapatkan nilai dari tipe yang tidak dapat diubah. Metode pabrik dapat mengembalikan objek yang telah dibuat sementara panggilan konstruktor selalu membuat objek baru.
Ada beberapa keuntungan lain untuk metode pabrik, tetapi mereka tidak terkait erat dengan keabadian dan API Tanggal-Waktu. Misalnya, metode pabrik memiliki nama dan mereka dapat mengembalikan objek dari beberapa subtipe.
sumber
Saya tidak mendesain atau menulis API Tanggal-Waktu Java, jadi saya tidak dapat secara definitif mengatakan "mengapa mereka melakukannya dengan cara ini." Namun saya dapat menyarankan dua alasan utama mereka harus melakukannya dengan cara ini:
Pertama, pertimbangkan konteksnya: Tanggal dan kode waktu Java adalah paket besar dan rumit yang berurusan dengan masalah yang sangat rumit. Seperti halnya "waktu", penerapan konsep melibatkan lusinan interpretasi dan format, dengan variasi di seluruh lokasi geografis (zona waktu), bahasa, sistem kalender, resolusi jam, skala waktu, representasi numerik, sumber data, dan interval. Delta korektif (misalnya tahun kabisat / hari) adalah umum, dan dapat dimasukkan secara tidak teratur kapan saja (detik kabisat). Namun paket tersebut adalah fitur inti, kemungkinan akan digunakan secara luas, dan diharapkan dapat menangani semua variasi tersebut dengan benar dan tepat. Ini tugas berat. Hasilnya, tidak mengherankan, adalah API yang kompleks termasuk banyak kelas, masing-masing dengan banyak metode.
Sekarang, mengapa menggunakan
of
metode daripada konstruktor kelas "biasa"? Untuk contoh , mengapaLocalDate.of(...)
,LocalDate.ofEpochDay(...)
danLocalDate.ofYearDay(...)
bukan hanya segelintirnew LocalDate(...)
panggilan?Pertama, kekuatan ekspresif : Metode individu bernama menyatakan maksud konstruksi dan bentuk data yang dikonsumsi.
Asumsikan sejenak bahwa kelebihan metode Java cukup untuk memungkinkan berbagai konstruktor yang Anda inginkan. (Tanpa membahas fitur bahasa di sekitar mengetik bebek dan pengiriman tunggal vs dinamis vs beberapa saya hanya akan mengatakan: kadang-kadang ini benar, kadang tidak. Untuk saat ini, anggap saja tidak ada batasan teknis.)
Mungkin saja dokumentasi konstruktor menyatakan "ketika hanya melewati satu
long
nilai tunggal , nilai itu ditafsirkan sebagai hitungan hari, bukan satu tahun." Jika tipe data tingkat rendah yang diteruskan ke konstruktor lain berbeda (mis. Hanya kasus zaman yang digunakanlong
, dan semua konstruktor lainnya digunakanint
), Anda mungkin lolos dengan ini.Jika Anda melihat kode memanggil
LocalDate
konstruktor dengan satulong
, itu akan terlihat sangat mirip dengan kode di mana satu tahun dilewatkan, terutama dengan melewati satu tahun bisa dibilang kasus yang paling umum. Memiliki konstruktor yang sama itu mungkin, tetapi itu tidak selalu mengarah pada kejelasan yang besar.Namun API yang secara eksplisit menyatakan
ofEpochDay
, menandakan perbedaan yang jelas dalam unit dan niat. Demikian pulaLocalDate.ofYearDay
menandakan bahwamonth
parameter umum sedang dilewati, dan bahwa parameter hari, sementara masih merupakanint
,dayOfYear
bukan adayOfMonth
. Metode konstruktor eksplisit dimaksudkan untuk mengungkapkan apa yang terjadi dengan kejelasan yang lebih besar.Bahasa yang diketik secara dinamis dan bebek seperti Python dan JavaScript memiliki cara lain untuk menandai interpretasi alternatif (misalnya parameter opsional dan nilai sentinel out-of-band ), tetapi bahkan pengembang Python dan JS sering menggunakan nama metode yang dibedakan untuk menandai interpretasi yang berbeda. Ini bahkan lebih umum di Jawa, mengingat kedua kendala teknisnya (itu adalah bahasa yang diketik secara statis, pengiriman tunggal) dan konvensi / idiom budaya.
Kedua, bentuk paralel .
LocalDate
dapat memberikan konstruktor Java standar sebagai tambahan, atau sebagai pengganti, duaof
metodenya. Tetapi untuk tujuan apa? Masih perluofEpochDay
danofDayYear
untuk kasus penggunaan tersebut. Beberapa kelas memang menyediakan konstruktor dan metode yang setaraofXYZ
- misalnya, keduanyaFloat('3.14')
danFloat.parseFloat('3.14')
ada. Tetapi jika Anda membutuhkanofXYZ
konstruktor untuk beberapa hal, mengapa tidak menggunakannya setiap saat? Itu lebih sederhana, lebih teratur, dan lebih paralel. Sebagai jenis berubah, yang mayoritas dariLocalDate
metode yang konstruktor. Ada kelompok utama tujuh metode yang membangun kasus baru (masing-masing,at
,from
,minus
,of
,parse
,plus
, danwith
awalan). DariLocalDate
60+ metode, 35+ adalah konstruktor de facto . Hanya 2 yang dapat dengan mudah dikonversi menjadi konstruktor berbasis kelas standar. Apakah benar-benar masuk akal untuk memberi case khusus pada keduanya dengan cara yang tidak paralel dengan yang lainnya? Apakah kode klien menggunakan dua konstruktor kasus khusus menjadi lebih jelas atau lebih sederhana? Mungkin tidak. Bahkan mungkin membuat kode klien lebih bervariasi dan kurang mudah.sumber