Maaf, saya tidak dapat menemukan pertanyaan untuk menjawab ini, saya hampir yakin orang lain telah mengangkatnya sebelumnya.
Masalah saya adalah saya sedang menulis beberapa pustaka sistem untuk menjalankan perangkat yang disematkan. Saya memiliki perintah yang dapat dikirim ke perangkat ini melalui siaran radio. Ini hanya dapat dilakukan dengan teks. di dalam perpustakaan sistem saya memiliki utas yang menangani perintah yang terlihat seperti ini
if (value.equals("A")) { doCommandA() }
else if (value.equals("B")) { doCommandB() }
else if etc.
Masalahnya adalah bahwa ada banyak perintah yang akan dengan cepat berubah menjadi sesuatu yang tidak terkendali. Mengerikan untuk diwaspadai, menyakitkan untuk di-debug, dan membingungkan untuk dipahami dalam waktu beberapa bulan.
Jawaban:
menggunakan pola Perintah :
lalu buat
Map<String,Command>
objek dan isi denganCommand
instance:maka Anda dapat mengganti rantai if / else if Anda dengan:
EDIT
Anda juga dapat menambahkan perintah khusus seperti
UnknownCommand
atauNullCommand
, tetapi Anda memerlukan perintahCommandMap
yang menangani kasus sudut ini untuk meminimalkan pemeriksaan klien.sumber
Saran saya akan menjadi semacam kombinasi ringan dari enum dan objek Command. Ini adalah idiom yang direkomendasikan oleh Joshua Bloch di Item 30 dari Java Efektif.
Tentu saja Anda bisa meneruskan parameter ke doCommand atau memiliki tipe kembalian.
Solusi ini mungkin tidak benar-benar cocok jika implementasi doCommand tidak benar-benar "sesuai" dengan jenis enum, yang - seperti biasa ketika Anda harus melakukan tradeoff - sedikit kabur.
sumber
Memiliki enum perintah:
Jika Anda memiliki lebih dari beberapa perintah, perhatikan penggunaan pola Command, seperti yang dijawab di tempat lain (meskipun Anda dapat mempertahankan enum dan menyematkan panggilan ke kelas implementasi dalam enum, alih-alih menggunakan HashMap). Silakan lihat jawaban Andreas atau jens untuk pertanyaan ini sebagai contoh.
sumber
Menerapkan antarmuka seperti yang didemonstrasikan secara sederhana dan jelas oleh dfa adalah bersih dan elegan (dan cara yang didukung "secara resmi"). Untuk inilah konsep antarmuka dimaksudkan.
Di C #, kita bisa menggunakan delegasi untuk programmer yang suka menggunakan penunjuk functon di c, tetapi teknik DFA adalah cara menggunakannya.
Anda juga bisa memiliki array
Kemudian Anda bisa menjalankan perintah dengan index
Menjiplak dari DFA, tetapi memiliki kelas dasar abstrak, bukan antarmuka. Perhatikan cmdKey yang akan digunakan nanti. Berdasarkan pengalaman, saya menyadari bahwa sering kali sebuah perintah peralatan memiliki sub-perintah juga.
Bangun perintah Anda demikian,
Anda kemudian dapat memperluas HashMap atau HashTable generik dengan menyediakan fungsi penghisapan pasangan nilai kunci:
Kemudian buat penyimpanan perintah Anda:
Sekarang Anda dapat mengirim kontrol secara objektif
sumber
Saya menyarankan untuk membuat objek perintah dan memasukkannya ke dalam hashmap menggunakan String sebagai Kunci.
sumber
Bahkan jika saya yakin pendekatan pola perintah lebih mengarah pada praktik terbaik dan dapat dipelihara dalam jangka panjang, berikut adalah satu opsi liner untuk Anda:
org.apache.commons.beanutils.MethodUtils.invokeMethod (ini, "doCommand" + nilai, null);
sumber
saya biasanya mencoba menyelesaikannya seperti itu:
ini memiliki banyak keuntungan:
1) tidak mungkin menambahkan enum tanpa mengimplementasikan exec. jadi Anda tidak akan melewatkan A.
2) Anda bahkan tidak perlu menambahkannya ke peta perintah apa pun, jadi tidak ada kode boilerplate untuk membuat peta. hanya metode abstrak dan implementasinya. (yang bisa dibilang juga boilerplate, tapi tidak akan menjadi lebih pendek ..)
3) Anda akan menyimpan siklus cpu yang terbuang dengan menelusuri daftar panjang if's atau menghitung kode hash dan melakukan pencarian.
edit: jika Anda tidak memiliki enum tetapi string sebagai sumber, cukup gunakan
Command.valueOf(mystr).exec()
untuk memanggil metode exec. perhatikan bahwa Anda harus menggunakan pengubah publik di execif yang ingin Anda panggil dari paket lain.sumber
Anda mungkin paling baik menggunakan Peta Perintah.
Tetapi apakah Anda memiliki satu set ini untuk ditangani, Anda berakhir dengan banyak Maps yang mengetuk. Maka itu layak untuk dilakukan dengan Enums.
Anda dapat melakukannya dengan Enum tanpa menggunakan sakelar (Anda mungkin tidak memerlukan getter dalam contoh), jika Anda menambahkan metode ke Enum untuk menyelesaikan "nilai". Kemudian Anda bisa melakukan:
Pembaruan: menambahkan peta statis untuk menghindari iterasi pada setiap panggilan. Dicubit tanpa malu dari jawaban ini .
sumber
Jawaban yang diberikan oleh @dfa adalah solusi terbaik menurut saya.
Saya hanya memberikan beberapa cuplikan jika Anda menggunakan Java 8 dan ingin menggunakan Lambdas!
Perintah tanpa parameter:
(Anda bisa menggunakan Runnable alih-alih Command, tetapi saya tidak menganggapnya benar secara semantik):
Perintah dengan satu parameter:
Jika Anda mengharapkan parameter yang dapat Anda gunakan
java.util.function.Consumer
:Dalam contoh di atas,
doSomethingX
adalah metode yang ada dimyObj
kelas yang mengambil Objek apa pun (dinamaiparam
dalam contoh ini) sebagai argumen.sumber
jika Anda memiliki beberapa pernyataan 'jika' imbricated, maka ini adalah pola untuk menggunakan mesin aturan . Lihat, misalnya JBOSS Drools .
sumber
Cukup gunakan HashMap, seperti yang dijelaskan di sini:
sumber
jika memungkinkan untuk memiliki serangkaian prosedur (yang Anda sebut perintah) yang akan berguna ..
tetapi Anda dapat menulis program untuk menulis kode Anda. Semuanya sangat sistematis jika (value = 'A') commandA (); lain jika (........................ dll
sumber
Saya tidak yakin apakah Anda memiliki tumpang tindih antara perilaku berbagai perintah Anda, tetapi Anda mungkin juga ingin melihat pola Chain Of Responsibility yang dapat memberikan lebih banyak fleksibilitas dengan mengizinkan banyak perintah untuk menangani beberapa nilai input.
sumber
Pola perintah adalah cara untuk pergi. Berikut salah satu contoh menggunakan java 8:
1. Tentukan antarmuka:
2. Implementasikan antarmuka dengan setiap ekstensi:
dan
dan seterusnya .....
3. Tentukan Klien:
4. Dan ini adalah contoh hasil:
sumber
Jika itu melakukan banyak hal, maka akan ada banyak kode, Anda tidak bisa benar-benar menjauh dari itu. Buatlah mudah untuk diikuti, beri nama variabel yang sangat berarti, komentar juga dapat membantu ...
sumber