Apakah penggunaan *** Helper atau *** Util class hanya berisi metode statis sebuah AntiPattern

19

Saya sering berhadapan dengan kelas pembantu atau kelas pemanfaatan di Jawa atau bahasa apa pun. Jadi saya bertanya pada diri saya sendiri apakah ini semacam Pola Anti dan keberadaan kelas-kelas semacam ini hanyalah kekurangan dalam desain dan arsitektur Perangkat Lunak.

Seringkali kelas-kelas ini dibatasi hanya dengan menggunakan metode statis, yang melakukan banyak hal. Tetapi sebagian besar memang tergantung pada konteks dan keadaan.

Pertanyaan saya adalah, apa pendapat Anda tentang jenis static helper / util class karena keuntungannya tentu saja adalah doa cepat hanya dengan menggunakan nama kelas.

Dan pada tingkat abstraksi seperti apa Anda akan menghindari penggunaan kelas-kelas semacam ini?

Menurut pendapat saya kata kunci "statis" seharusnya diperbolehkan dalam deklarasi kelas (Java) dan bukan untuk metode. Menurut pendapat saya, menggunakannya dengan cara ini, ini bisa menjadi alternatif dan middleway yang baik untuk dapat menggabungkan Paradigma Procuedural- dan OO di Jawa dan menghindari penyalahgunaan kata kunci.

Penambahan karena jawaban:

Pada awalnya saya berpikir bahwa itu benar-benar legal untuk dapat menggabungkan paradigma yang berbeda dan bahkan menggunakan bahasa scripting yang ditafsirkan runtime dalam mesin atau kode yang disusun vm.

Pengalaman saya adalah bahwa selama proses pengembangan proyek semacam pembantu dan utilitas atau apa pun namanya, tumbuh dan tumbuh dan digunakan di setiap sudut basis kode yang terlupakan, yang awalnya dirancang untuk modular dan fleksibel. Dan karena kurangnya waktu untuk membuat refactorings atau memikirkan desain lagi Anda hanya membuatnya jauh lebih buruk dari waktu ke waktu.

Saya pikir staticharus dihapus dari Jawa. Apalagi sekarang di mana dimungkinkan untuk menggunakan elemen bahasa fungsional yang lebih canggih.

Perbedaan
sumber
2
Kemungkinan duplikat Apa kegunaan kelas statis yang valid?
Agak
Saya pikir jika penolong tidak perlu membuat kelas, itu baik-baik saja. Masalahnya adalah ketika penolong instantiates implementasi konkret dari sebuah kelas dan kemudian Anda tidak dapat mengejek antarmuka itu. Jika pembantu dilewatkan antarmuka atau kelas abstrak saya pikir tidak apa-apa.
bobek
Tidak masalah jika Anda mengklaim melakukan pemrograman prosedural. Itu tidak jika Anda mengklaim melakukan pemrograman objek (berorientasi).
Terlihat
1
@Spotted: dan karena tidak ada nilai bisnis dalam mengklaim Anda hanya pemrograman berorientasi objek, hanya selalu melakukan pemrograman paradigma campuran dan menyelesaikannya.
RemcoGerlich
@RemcoGerlich Tepat. Maksud saya adalah untuk mencatat bahwa jawabannya terutama "filosofis", terkait dengan paradigma pemrograman mana yang Anda pertimbangkan.
Terlihat

Jawaban:

20

Yah, Java tidak memiliki fungsi gratis, jadi Anda terpaksa menempatkannya sebagai fungsi statis ke dalam beberapa kelas pro-forma. Upaya yang diperlukan tidak pernah anti-pola, meskipun mungkin tidak memiliki keanggunan.

Selanjutnya, tidak ada yang salah dengan fungsi gratis. Sebenarnya, menggunakan fungsi gratis mengurangi kopling, karena mereka hanya memiliki akses ke antarmuka publik alih-alih semua detail berdarah.

Tentu saja, menggunakan fungsi bebas / statis tidak dengan cara apa pun mengurangi bahaya negara yang bisa berubah, terutama global.

Deduplicator
sumber
2
@TimothyTruckle Entah mereka statis, atau mereka memiliki berlebihan this, dan memerlukan sesuatu yang dipakai tepat
Caleth
6
@TimothyTruckle Karena itu Java. Bahasa lain dapat memiliki fungsi bebas tanpa harus memasukkannya ke dalam kelas hanya untuk menyatakan itu bukan metode turunan. Dan pada titik tertentu, Anda harus memiliki kopling ketat. Apakah itu baik atau tidak sepenuhnya terserah apa fungsi tersebut tidak .
nvoigt
5
@TimothyTruckle Tentu saja, mempertahankan status akan menjadi alasan utama untuk menjadi "tidak baik".
novigt
2
@nigt, saya merasa jawaban ini akan sangat ditingkatkan dengan secara eksplisit menyatakan titik itu. Statika stateful adalah buruk; yang tanpa kewarganegaraan itu baik. Sangat sederhana.
David Arno
3
@ TimothyTruckle Itu bukan kopling ketat. Anda sedang menggambarkan sambungan longgar. Kopling ketat dalam konteks ini akan menyiratkan semacam saling ketergantungan. Ketergantungan satu arah tidak memenuhi persyaratan itu.
JimmyJames
18

Utilitas statis atau fungsi pembantu bukan merupakan pola anti jika mereka mematuhi beberapa pedoman:

  1. Mereka harus bebas dari efek samping

  2. Mereka digunakan untuk perilaku spesifik aplikasi yang tidak termasuk dalam kelas atau kelas di mana fungsi ini beroperasi

  3. Mereka tidak memerlukan status bersama

Kasus penggunaan umum:

  • Memformat tanggal dengan cara khusus aplikasi
  • Fungsi yang mengambil satu jenis sebagai input dan mengembalikan jenis yang berbeda.

Misalnya dalam aplikasi saya bekerja pada pengguna menyimpan entri jurnal untuk kegiatan mereka. Mereka dapat menentukan tanggal tindak lanjut dan mengunduh pengingat acara. Kami membuat kelas utilitas statis untuk mengambil entri jurnal dan mengembalikan teks mentah untuk file .ics.

Itu tidak memerlukan keadaan bersama. Itu tidak mengubah keadaan apa pun, dan membuat acara iCal jelas merupakan aplikasi khusus dan tidak termasuk dalam kelas entri jurnal.

Jika fungsi statis atau kelas utilitas memiliki efek samping atau memerlukan status bersama, saya akan merekomendasikan untuk mengevaluasi kembali kode ini, karena mengenalkan kopling yang mungkin sulit dipermainkan untuk pengujian unit.

Greg Burghardt
sumber
4

Itu akan tergantung pada pendekatan Anda. Banyak aplikasi yang ditulis dengan lebih fungsional, tidak seperti pola pikir klasik (termasuk banyak situs tempat Anda berada).

Dengan pola pikir ini, akan ada banyak metode utilitas pada kelas pekerja yang dapat dirangkai sebagai metode statis. Mereka diberi makan / digunakan lebih dekat ke objek polos yang hanya menampung data dan bisa diedarkan.

Ini adalah pendekatan yang valid dan dapat bekerja dengan sangat baik, terutama pada skala.

Pelacak1
sumber
"dapat bekerja dengan sangat baik, terutama pada skala" Tidak. Kopling ketat yang disebabkan oleh akses statis akan segera menghalangi jalan Anda saat proyek tumbuh.
Timothy Truckle
@TimothyTruckle Bisakah Anda menjelaskan bagaimana Agent.Save (obj) jauh lebih erat daripada obj.Save ()? Agen sama mampu mendapatkan referensi DI / IoC, bahkan untuk metode statis sebagai contoh kelas. Sebagai referensi, Stack Exchange sendiri ditulis dengan pola pikir seperti ini, dan telah ditingkatkan skalanya lebih baik daripada aplikasi ASP.Net lainnya dengan sumber daya yang lebih sedikit daripada yang saya ketahui.
Pelacak1
"Bisakah kamu menjelaskan bagaimana Agent. Simpan (obj) jauh lebih erat daripada obj. Simpan ()?" Ini adalah contoh yang salah. Sebuah contoh yang benar akan Agent.Save(obj)vs agentInstance.Save(obj). Dengan yang terakhir Anda memiliki kemungkinan untuk menyuntikkan agentInstance ke dalam kode menggunakan. Karena Anda dapat menyuntikkan setiap kelas anak dari Agentterlalu yang memungkinkan penggunaan kembali og kode menggunakan dengan berbeda "jenis" dari Agenttanpa mengkompilasi ulang. Ini kopling rendah .
Timothy Truckle
Saya pikir itu benar-benar bermuara pada beberapa hal. Apakah negara diperlukan, seberapa fleksibel negara tersebut, dan apakah boleh memiliki keadaan global / instan? Terserah masing-masing pengembang / arsitek untuk memutuskan. Saya lebih suka basis kode sederhana daripada menambahkan kompleksitas untuk skenario yang membuat semuanya lebih sulit untuk dipahami secara keseluruhan. Salah satu hal yang saya sukai dari node / js adalah saya dapat menulis kode sederhana / bersih dan masih menyuntikkan untuk pengujian tanpa kode yang ditulis ke DI / IoC spesifik.
Tracker1
2

Saya pribadi berpikir satu-satunya bagian penting tentang kelas-kelas penolong semacam itu adalah bahwa kelas itu dibuat pribadi. Selain itu - mereka benar-benar ide yang bagus (diterapkan dengan hemat).

Cara saya berpikir tentang ini - adalah jika dalam mengimplementasikan sebuah kelas (atau fungsi) - sesuatu seperti ini sangat membantu, dan membuat implementasi itu lebih jelas, bagaimana mungkin itu buruk? Dan SERING itu penting untuk mendefinisikan kelas pembantu pribadi untuk memungkinkan integrasi dengan dan penggunaan algoritma lain yang bergantung pada data yang berada dalam bentuk tertentu.

Apakah memberi label 'penolong' adalah masalah kecil selera pribadi, tetapi berkonotasi bahwa hal itu membantu dalam implementasi dan itu tidak menarik / digunakan untuk audiens yang lebih luas. Jika itu yang masuk akal - lakukanlah!

Lewis Pringle
sumber
1
Kelas utilitas publik mungkin masih bermanfaat. Contoh utama: java.lang.Math.
amon
1

Prevalensi statickelas penolong di didasarkan pada kesalahpahaman. Hanya karena kita memanggil kelas dengan hanya staticmetode "kelas utilitas" tidak berarti bahwa itu tidak diperbolehkan untuk menulis perilaku umum di POJO.

static kelas pembantu adalah anti pola karena tiga alasan:

  1. Akses statis ke metode pembantu ini menyembunyikan ketergantungan . Jika "kelas utilitas" ini adalah POJO, Anda bisa menyuntikkannya ke kelas dependen sebagai parameter konstruktor yang akan membuat ketergantungannya jelas bagi setiap pengguna kelas dependen.

  2. Akses statis ke metode pembantu ini menyebabkan kopling ketat . Ini berarti bahwa kode yang menggunakan metode pembantu sulit untuk digunakan kembali dan (sebagai efek samping) cepat untuk diuji.

  3. Terutama jika mereka mempertahankan negara, ini hanyalah variabel global . Dan mudah-mudahan tidak ada yang berpendapat bahwa variabel global bagus ...

Kelas pembantu statis adalah bagian dari pola anti- kode STUPID .


Keadaan global tidak terkait dengan pertanyaan, - max630

OP menulis:

Tetapi sebagian besar memang tergantung pada konteks dan keadaan.

Konstruk statefull statis adalah negara global.

segala jenis kode dapat menggunakannya. - maks 630

Ya, karena sebab. Dan hampir semua aplikasi membutuhkan semacam kondisi global .

Tetapi keadaan global ! = Variabel global .

Anda dapat membuat keadaan global dengan teknik OO melalui injeksi ketergantungan Tetapi Anda tidak dapat menghindari keadaan global dengan struktur statis statefull yang merupakan variabel global di bagian bawah.

Timothy Truckle
sumber
2
Keadaan global tidak terkait dengan pertanyaan, kode apa pun dapat menggunakannya.
maks 630
@ max630 silakan lihat pemutakhiran saya
Timothy Truckle
1
Anda dapat menggunakan fungsi bebas statis tanpa sambungan. Anda membagikan Func<Result, Args>objek, yang dipakai di tempat lain.
Caleth
1
1) Saya biasanya berpikir bahwa implementasi menyembunyikan adalah hal yang baik, di mana itu cocok. 2) Memiliki segala sesuatu sebagai argumen / ketergantungan-disuntikkan juga menciptakan semacam penggabungan waktu-desain, Anda bisa merasakan ini ketika Anda harus menghabiskan banyak waktu untuk mengubah tanda tangan dalam rantai ketergantungan lama. Dan seperti memiliki setiap fungsi tunggal yang memerlukan Logger Anda, atau masalah lintas sektoral lainnya, sebagai argumen, urgh ... (Tapi ya, itu dapat membuat pengujian tingkat rendah lebih sulit) 3) Tentu saja fungsi statis harus stateless.
Alex
1
@Alex Lalu izinkan saya mengatakannya sebaliknya: Unit adalah sekumpulan kode (termasuk metode "utilitas" yang dirujuk secara statis) yang memiliki alasan yang sama untuk berubah . Apa pun di dalam unit ini adalah detail implementasi . Yang lainnya adalah ketergantungan , dan unit tidak boleh memiliki akses statis ke sana.
Timothy Truckle