Terkadang, kami harus menulis metode yang menerima banyak argumen, misalnya:
public void doSomething(Object objA , Object objectB ,Date date1 ,Date date2 ,String str1 ,String str2 )
{
}
Ketika saya menghadapi masalah seperti ini, saya sering merangkum argumen ke dalam peta.
Map<Object,Object> params = new HashMap<Object,Object>();
params.put("objA",ObjA) ;
......
public void doSomething(Map<Object,Object> params)
{
// extracting params
Object objA = (Object)params.get("objA");
......
}
Ini bukan praktik yang baik, merangkum parameter ke dalam peta benar-benar membuang-buang efisiensi. Hal baiknya adalah, tanda tangan yang bersih, mudah untuk menambahkan parameter lain dengan modifikasi paling sedikit. apa praktik terbaik untuk jenis masalah ini?
java
performance
parameters
parameter-passing
Penggergaji
sumber
sumber
Menggunakan peta dengan kunci String ajaib adalah ide yang buruk. Anda kehilangan pemeriksaan waktu kompilasi, dan sangat tidak jelas apa parameter yang diperlukan. Anda perlu menulis dokumentasi yang sangat lengkap untuk menebusnya. Akankah Anda ingat dalam beberapa minggu apa itu String tanpa melihat kodenya? Bagaimana jika Anda salah ketik? Gunakan tipe yang salah? Anda tidak akan mengetahuinya sampai Anda menjalankan kode.
Sebaliknya gunakan model. Buat kelas yang akan menjadi wadah untuk semua parameter tersebut. Dengan begitu Anda menjaga keamanan tipe Java. Anda juga dapat meneruskan objek itu ke metode lain, memasukkannya ke dalam koleksi, dll.
Tentu saja jika kumpulan parameter tidak digunakan di tempat lain atau disebarkan, model khusus mungkin berlebihan. Ada keseimbangan yang harus dicapai, jadi gunakan akal sehat.
sumber
Jika Anda memiliki banyak parameter opsional, Anda dapat membuat API yang lancar: ganti metode tunggal dengan rangkaian metode
exportWithParams().datesBetween(date1,date2) .format("xml") .columns("id","name","phone") .table("angry_robots") .invoke();
Menggunakan impor statis Anda dapat membuat API fasih dalam:
sumber
Ini disebut "Perkenalkan Objek Parameter". Jika Anda mendapati diri Anda meneruskan daftar parameter yang sama di beberapa tempat, cukup buat kelas yang menampung semuanya.
XXXParameter param = new XXXParameter(objA, objB, date1, date2, str1, str2); // ... doSomething(param);
Meskipun Anda tidak terlalu sering menyampaikan daftar parameter yang sama, pemfaktoran ulang yang mudah itu masih akan meningkatkan keterbacaan kode Anda, yang selalu bagus. Jika Anda melihat kode Anda 3 bulan kemudian, akan lebih mudah untuk memahaminya ketika Anda perlu memperbaiki bug atau menambahkan fitur.
Ini adalah filosofi umum tentu saja, dan karena Anda belum memberikan detail apa pun, saya juga tidak dapat memberikan saran yang lebih detail. :-)
sumber
XXXParameter param = new XXXParameter();
tersedia, dan kemudian menggunakanXXXParameter.setObjA(objA)
; dll ...Pertama, saya akan mencoba memfaktorkan ulang metode ini. Jika menggunakan banyak parameter, mungkin akan terlalu panjang. Memecahnya akan meningkatkan kode dan berpotensi mengurangi jumlah parameter untuk setiap metode. Anda mungkin juga dapat melakukan refaktorisasi seluruh operasi ke kelasnya sendiri. Kedua, saya akan mencari contoh lain di mana saya menggunakan yang sama (atau superset) dari daftar parameter yang sama. Jika Anda memiliki beberapa contoh, kemungkinan itu menandakan bahwa properti ini dimiliki bersama. Dalam hal ini, buat kelas untuk menampung parameter dan menggunakannya. Terakhir, saya akan mengevaluasi apakah jumlah parameter membuatnya layak untuk dibuat objek peta untuk meningkatkan keterbacaan kode. Saya pikir ini adalah panggilan pribadi - ada kesulitan masing-masing dengan solusi ini dan di mana titik trade-off mungkin berbeda. Untuk enam parameter saya mungkin tidak akan melakukannya. Untuk 10 saya mungkin akan (jika tidak ada metode lain yang berhasil terlebih dahulu).
sumber
Ini sering menjadi masalah saat membangun objek.
Dalam kasus tersebut, gunakan pola objek pembangun , ini berfungsi dengan baik jika Anda memiliki daftar parameter yang besar dan tidak selalu membutuhkan semuanya.
Anda juga dapat menyesuaikannya dengan pemanggilan metode.
Ini juga meningkatkan banyak keterbacaan.
public class BigObject { // public getters // private setters public static class Buider { private A f1; private B f2; private C f3; private D f4; private E f5; public Buider setField1(A f1) { this.f1 = f1; return this; } public Buider setField2(B f2) { this.f2 = f2; return this; } public Buider setField3(C f3) { this.f3 = f3; return this; } public Buider setField4(D f4) { this.f4 = f4; return this; } public Buider setField5(E f5) { this.f5 = f5; return this; } public BigObject build() { BigObject result = new BigObject(); result.setField1(f1); result.setField2(f2); result.setField3(f3); result.setField4(f4); result.setField5(f5); return result; } } } // Usage: BigObject boo = new BigObject.Builder() .setField1(/* whatever */) .setField2(/* whatever */) .setField3(/* whatever */) .setField4(/* whatever */) .setField5(/* whatever */) .build();
Anda juga bisa meletakkan logika verifikasi ke dalam metode set .. () dan build () Builder.
sumber
final
? Ini adalah hal utama yang membuat saya tidak dapat menulis fungsi pembantu. Saya kira saya dapat membuat bidang menjadi pribadi dan memastikan saya tidak memodifikasinya dengan benar dalam kode kelas itu, tetapi saya berharap untuk sesuatu yang lebih elegan.Ada pola yang disebut sebagai objek Parameter .
Idealnya adalah menggunakan satu objek sebagai pengganti semua parameter. Sekarang meskipun Anda perlu menambahkan parameter nanti, Anda hanya perlu menambahkannya ke objek. Antarmuka metode tetap sama.
sumber
Anda dapat membuat kelas untuk menyimpan data tersebut. Perlu cukup bermakna, tetapi jauh lebih baik daripada menggunakan peta (OMG).
sumber
Code Complete * menyarankan beberapa hal:
* Edisi Pertama, saya tahu saya harus memperbarui. Selain itu, nampaknya beberapa dari saran ini mungkin telah berubah sejak edisi kedua ditulis ketika OOP mulai menjadi lebih populer.
sumber
Praktik yang baik adalah refactor. Bagaimana dengan benda-benda ini yang berarti mereka harus diteruskan ke metode ini? Haruskah mereka dikemas menjadi satu objek?
sumber
Menggunakan Peta adalah cara sederhana untuk membersihkan tanda panggilan tetapi Anda memiliki masalah lain. Anda perlu melihat ke dalam tubuh metode untuk melihat apa yang diharapkan metode di Peta itu, apa nama kunci atau jenis nilai yang dimiliki.
Cara yang lebih bersih adalah dengan mengelompokkan semua parameter dalam objek bean tetapi itu masih tidak memperbaiki masalah sepenuhnya.
Apa yang Anda miliki di sini adalah masalah desain. Dengan lebih dari 7 parameter ke sebuah metode, Anda akan mulai memiliki masalah dalam mengingat apa yang mereka wakili dan urutan apa yang mereka miliki. Dari sini Anda akan mendapatkan banyak bug hanya dengan memanggil metode dengan urutan parameter yang salah.
Anda memerlukan desain aplikasi yang lebih baik, bukan praktik terbaik untuk mengirim banyak parameter.
sumber
Buat kelas kacang, dan setel semua parameter (metode penyetel) dan teruskan objek kacang ini ke metode.
sumber
Lihat kode Anda, dan lihat mengapa semua parameter itu diteruskan. Kadang-kadang dimungkinkan untuk memfaktor ulang metode itu sendiri.
Menggunakan peta membuat metode Anda rentan. Bagaimana jika seseorang yang menggunakan metode Anda salah mengeja nama parameter, atau memposting string di mana metode Anda mengharapkan UDT?
Tentukan Objek Transfer . Ini akan memberi Anda pemeriksaan jenis paling tidak; bahkan mungkin bagi Anda untuk melakukan beberapa validasi pada titik penggunaan alih-alih dalam metode Anda.
sumber
Ini sering kali merupakan indikasi bahwa kelas Anda memiliki lebih dari satu tanggung jawab (yaitu, kelas Anda melakukan JUGA banyak).
Lihat Prinsip Tanggung Jawab Tunggal
untuk keterangan lebih lanjut.
sumber
Jika Anda memberikan terlalu banyak parameter, coba lakukan refaktorisasi metode. Mungkin ia melakukan banyak hal yang seharusnya tidak dilakukan. Jika bukan itu masalahnya, coba gantikan parameter dengan satu kelas. Dengan cara ini Anda dapat merangkum semuanya dalam satu instance kelas dan meneruskan instance tersebut dan bukan parameternya.
sumber
Saya akan mengatakan tetap dengan cara Anda melakukannya sebelumnya. Jumlah parameter dalam contoh Anda tidak banyak, tetapi alternatifnya jauh lebih mengerikan.
Peta - Ada hal efisiensi yang Anda sebutkan, tetapi masalah yang lebih besar di sini adalah:
lain ... Apakah Anda memiliki javadocs yang menyatakan dengan tepat kunci dan
nilai apa yang digunakan? Jika Anda melakukannya (yang bagus), maka memiliki banyak parameter juga tidak menjadi masalah.
Objek pembungkus - ini hanya memindahkan masalah karena Anda perlu mengisi objek pembungkus di tempat pertama - alih-alih langsung ke metode Anda, ini akan menjadi konstruktor dari objek parameter. Untuk menentukan apakah memindahkan masalah itu tepat atau tidak tergantung pada penggunaan kembali benda tersebut. Contohnya:
Tidak akan menggunakannya: Ini hanya akan digunakan sekali pada panggilan pertama, jadi banyak kode tambahan untuk menangani 1 baris ...?
Dapat menggunakannya: Di sini, dapat melakukan sedikit lebih banyak. Pertama, ini dapat memfaktorkan parameter untuk 3 panggilan metode. itu juga dapat melakukan 2 baris lain dalam dirinya sendiri ... sehingga menjadi variabel keadaan dalam arti ...
Hal lain yang orang lupa pertimbangkan adalah peran IDE dalam semua ini. Ketika metode memiliki parameter, IDE menghasilkan sebagian besar kode untuk Anda, dan Anda memiliki garis merah yang mengingatkan Anda apa yang perlu Anda berikan / setel. Saat menggunakan opsi 3 ... Anda kehilangan ini sepenuhnya. Sekarang terserah programmer untuk melakukannya dengan benar, dan tidak ada isyarat selama pengkodean dan waktu kompilasi ... programmer harus mengujinya untuk mengetahuinya.
Selain itu, opsi 2 dan 3, jika diadopsi dengan penyebaran yang tidak perlu, memiliki implikasi negatif jangka panjang dalam hal pemeliharaan karena banyaknya kode duplikat yang dihasilkannya. Semakin banyak kode yang ada, semakin banyak yang harus dipelihara, semakin banyak waktu dan uang yang dihabiskan untuk memeliharanya.
sumber