Saya memiliki kelas yang penuh dengan fungsi utilitas. Instantiasi contoh itu tidak masuk akal semantik, tapi saya masih ingin menyebut metodenya. Apa cara terbaik untuk menghadapi ini? Kelas statis? Abstrak?
@matt b: Seperti yang ditunjukkan David Robles dalam jawabannya, Anda tidak perlu membuat kelas menjadi final ... itu tidak dapat disubklasifikasikan karena subkelas tidak akan dapat memanggil konstruktor kelas super karena sifatnya pribadi. Namun ... tidak ada salahnya menjadi eksplisit. Tapi jfyi :-).
Butir 4: Menegakkan noninstantiability dengan konstruktor pribadi
- Berusaha untuk menegakkan noninstantiability dengan membuat abstrak kelas tidak berfungsi.
- Konstruktor default dihasilkan hanya jika kelas tidak mengandung konstruktor eksplisit, sehingga kelas dapat dibuat tidak dapat dibuktikan dengan menyertakan konstruktor pribadi:
// Noninstantiable utility classpublicclassUtilityClass{// Suppress default constructor for noninstantiabilityprivateUtilityClass(){thrownewAssertionError();}}
Karena konstruktor eksplisit bersifat privat, konstruktor tidak dapat diakses di luar kelas. AssertionError tidak sepenuhnya diperlukan, tetapi menyediakan asuransi jika konstruktor secara tidak sengaja dipanggil dari dalam kelas. Ini menjamin bahwa kelas tidak akan pernah dipakai dalam keadaan apa pun. Ungkapan ini agak berlawanan dengan intuisi, karena konstruktor disediakan secara tegas sehingga tidak dapat dipanggil. Oleh karena itu bijaksana untuk memasukkan komentar, seperti yang ditunjukkan di atas.
Sebagai efek samping, idiom ini juga mencegah kelas menjadi subclass. Semua konstruktor harus memanggil konstruktor superclass, secara eksplisit atau implisit, dan subkelas tidak memiliki konstruktor superclass yang dapat diakses untuk dipanggil.
Kedengarannya seperti Anda memiliki kelas utilitas yang mirip dengan java.lang.Math .
Pendekatannya ada kelas akhir dengan konstruktor pribadi dan metode statis.
Hanya untuk berenang di hulu, anggota dan kelas statis tidak berpartisipasi dalam OO dan karenanya jahat. Tidak, tidak jahat, tapi serius, saya akan merekomendasikan kelas reguler dengan pola akses tunggal. Dengan cara ini jika Anda perlu mengesampingkan perilaku dalam kasus apa pun di jalan, itu bukan perombakan besar. OO adalah temanmu :-)
tunggal tidak lebih jahat dari injeksi ketergantungan :)
irreputable
12
OO memiliki tempatnya, tetapi ada kalanya itu tidak praktis, atau itu akan menjadi pemborosan sumber daya - misalnya, sesuatu yang sederhana seperti Math.abs (). Tidak ada alasan untuk instantiate objek hanya demi instantiate objek, ketika panggilan metode statis akan melayani Anda dengan baik tanpa OO-overhead. ;)
merampok
2
@rob re OO, saya setuju, Math.Abs mungkin tidak pernah membutuhkan sebuah instance. Ketika saya mendengar "saya memiliki kelas utilitas", saya melihat Math.Avg (), di mana Anda sekarang perlu menambahkan dukungan untuk rata-rata tertimbang. Saya melihat generator Url, param in, url yang perlu di refactored untuk mendukung href, atau hanya url, dll. Untuk alasan ini, memiliki kelas utilitas berbasis OO dapat membayar kembali. Juga, sekarang saya akan menjatuhkan taktik defensif standar OO, pengujian! / Me bebek
Bennett Dill
3
mengomentari argumen "konstruktor pribadi": ayolah, pengembang tidak sebodoh itu; tapi mereka malas. membuat objek lalu memanggil metode statis? tidak akan terjadi.
jangan menghabiskan terlalu banyak waktu untuk memastikan kelas Anda tidak dapat disalahgunakan. memiliki keyakinan untuk kolega Anda. dan selalu ada cara untuk menyalahgunakan kelas Anda tidak peduli bagaimana Anda melindunginya. satu-satunya hal yang tidak dapat disalahgunakan adalah hal yang sama sekali tidak berguna.
Seseorang yang telah melihat (dalam kode produksi, bukan hanya kode siswa) object.staticMethod Saya pikir Anda melebih-lebihkan kemampuan Joe Random Programmer! :-P
TofuBeer
2
Kelas terakhir dan konstruktor pribadi (baik tetapi tidak penting)
Tidak ada gunanya mendeklarasikan kelas sebagai static. Cukup deklarasikan metodenya staticdan panggil mereka dari nama kelas seperti biasa, seperti kelas Matematika Java .
Juga, meskipun tidak sepenuhnya membuat konstruktor pribadi, itu ide yang baik untuk melakukannya. Menandai konstruktor pribadi mencegah orang lain membuat instance kelas Anda, lalu memanggil metode statis dari instance tersebut. (Panggilan ini bekerja persis sama di Jawa, mereka hanya menyesatkan dan merusak keterbacaan kode Anda.)
Jawaban:
Konstruktor pribadi dan metode statis pada kelas ditandai sebagai final.
sumber
Menurut buku hebat "Java Efektif" :
Butir 4: Menegakkan noninstantiability dengan konstruktor pribadi
- Berusaha untuk menegakkan noninstantiability dengan membuat abstrak kelas tidak berfungsi.
- Konstruktor default dihasilkan hanya jika kelas tidak mengandung konstruktor eksplisit, sehingga kelas dapat dibuat tidak dapat dibuktikan dengan menyertakan konstruktor pribadi:
Karena konstruktor eksplisit bersifat privat, konstruktor tidak dapat diakses di luar kelas. AssertionError tidak sepenuhnya diperlukan, tetapi menyediakan asuransi jika konstruktor secara tidak sengaja dipanggil dari dalam kelas. Ini menjamin bahwa kelas tidak akan pernah dipakai dalam keadaan apa pun. Ungkapan ini agak berlawanan dengan intuisi, karena konstruktor disediakan secara tegas sehingga tidak dapat dipanggil. Oleh karena itu bijaksana untuk memasukkan komentar, seperti yang ditunjukkan di atas.
Sebagai efek samping, idiom ini juga mencegah kelas menjadi subclass. Semua konstruktor harus memanggil konstruktor superclass, secara eksplisit atau implisit, dan subkelas tidak memiliki konstruktor superclass yang dapat diakses untuk dipanggil.
sumber
AssertionError
atas alternatif lain sepertiIllegalStateException
,UnsupportedOperationException
, dll?Kedengarannya seperti Anda memiliki kelas utilitas yang mirip dengan java.lang.Math .
Pendekatannya ada kelas akhir dengan konstruktor pribadi dan metode statis.
Tetapi berhati-hatilah dengan apa yang dilakukan untuk testabilitas, saya sarankan membaca artikel ini.
Metode Statis adalah Kematian untuk Testabilitas
sumber
Hanya untuk berenang di hulu, anggota dan kelas statis tidak berpartisipasi dalam OO dan karenanya jahat. Tidak, tidak jahat, tapi serius, saya akan merekomendasikan kelas reguler dengan pola akses tunggal. Dengan cara ini jika Anda perlu mengesampingkan perilaku dalam kasus apa pun di jalan, itu bukan perombakan besar. OO adalah temanmu :-)
$ 0,02 saya
sumber
mengomentari argumen "konstruktor pribadi": ayolah, pengembang tidak sebodoh itu; tapi mereka malas. membuat objek lalu memanggil metode statis? tidak akan terjadi.
jangan menghabiskan terlalu banyak waktu untuk memastikan kelas Anda tidak dapat disalahgunakan. memiliki keyakinan untuk kolega Anda. dan selalu ada cara untuk menyalahgunakan kelas Anda tidak peduli bagaimana Anda melindunginya. satu-satunya hal yang tidak dapat disalahgunakan adalah hal yang sama sekali tidak berguna.
sumber
sumber
Tidak ada gunanya mendeklarasikan kelas sebagai
static
. Cukup deklarasikan metodenyastatic
dan panggil mereka dari nama kelas seperti biasa, seperti kelas Matematika Java .Juga, meskipun tidak sepenuhnya membuat konstruktor pribadi, itu ide yang baik untuk melakukannya. Menandai konstruktor pribadi mencegah orang lain membuat instance kelas Anda, lalu memanggil metode statis dari instance tersebut. (Panggilan ini bekerja persis sama di Jawa, mereka hanya menyesatkan dan merusak keterbacaan kode Anda.)
sumber
Anda dapat menggunakan anotasi @UtilityClass dari lombok https://projectlombok.org/features/experimental/UtilityClass
sumber