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:
- Kekuatan ekspresif
- Bentuk paralel
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 , mengapa LocalDate.of(...)
, LocalDate.ofEpochDay(...)
dan LocalDate.ofYearDay(...)
bukan hanya segelintir new 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 digunakan long
, dan semua konstruktor lainnya digunakan int
), Anda mungkin lolos dengan ini.
Jika Anda melihat kode memanggil LocalDate
konstruktor dengan satu long
, 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 pula LocalDate.ofYearDay
menandakan bahwa month
parameter umum sedang dilewati, dan bahwa parameter hari, sementara masih merupakan int
, dayOfYear
bukan a dayOfMonth
. 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, dua of
metodenya. Tetapi untuk tujuan apa? Masih perlu ofEpochDay
dan ofDayYear
untuk kasus penggunaan tersebut. Beberapa kelas memang menyediakan konstruktor dan metode yang setara ofXYZ
- misalnya, keduanya Float('3.14')
dan Float.parseFloat('3.14')
ada. Tetapi jika Anda membutuhkan ofXYZ
konstruktor untuk beberapa hal, mengapa tidak menggunakannya setiap saat? Itu lebih sederhana, lebih teratur, dan lebih paralel. Sebagai jenis berubah, yang mayoritas dari LocalDate
metode yang konstruktor. Ada kelompok utama tujuh metode yang membangun kasus baru (masing-masing, at
, from
, minus
, of
, parse
,plus
, dan with
awalan). Dari LocalDate
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.