Saya menulis layanan web di Java, dan saya mencoba mencari cara terbaik untuk menentukan kode kesalahan dan string kesalahan yang terkait . Saya perlu memiliki kode kesalahan numerik dan string kesalahan yang dikelompokkan bersama. Baik kode kesalahan dan string kesalahan akan dikirim ke klien yang mengakses layanan web. Misalnya, ketika SQLException terjadi, saya mungkin ingin melakukan hal berikut:
// Example: errorCode = 1,
// errorString = "There was a problem accessing the database."
throw new SomeWebServiceException(errorCode, errorString);
Program klien mungkin akan melihat pesan:
"Kesalahan # 1 telah terjadi: Ada masalah saat mengakses database."
Pikiran pertama saya adalah menggunakan salah Enum
satu kode kesalahan dan mengganti toString
metode untuk mengembalikan string kesalahan. Inilah yang saya dapatkan:
public enum Errors {
DATABASE {
@Override
public String toString() {
return "A database error has occured.";
}
},
DUPLICATE_USER {
@Override
public String toString() {
return "This user already exists.";
}
},
// more errors follow
}
Pertanyaan saya adalah: Apakah ada cara yang lebih baik untuk melakukan ini? Saya lebih suka solusi dalam kode, daripada membaca dari file eksternal. Saya menggunakan Javadoc untuk proyek ini, dan dapat mendokumentasikan kode kesalahan secara in-line dan memperbaruinya secara otomatis dalam dokumentasi akan sangat membantu.
Jawaban:
Tentu ada implementasi yang lebih baik dari solusi enum (yang umumnya cukup bagus):
Anda mungkin ingin mengganti toString () untuk mengembalikan deskripsi saja - tidak yakin. Bagaimanapun, poin utamanya adalah Anda tidak perlu mengganti secara terpisah untuk setiap kode kesalahan. Perhatikan juga bahwa saya secara eksplisit menentukan kode daripada menggunakan nilai ordinal - ini membuatnya lebih mudah untuk mengubah urutan dan menambah / menghapus kesalahan nanti.
Jangan lupa bahwa ini sama sekali tidak diinternasionalkan - tetapi kecuali klien layanan web Anda mengirimi Anda deskripsi lokal, Anda tetap tidak dapat menginternasionalkan dengan mudah. Setidaknya mereka akan memiliki kode kesalahan untuk digunakan untuk i18n di sisi klien ...
sumber
Sejauh yang saya ketahui, saya lebih suka mengeksternalisasi pesan kesalahan dalam file properti. Ini akan sangat membantu dalam kasus internasionalisasi aplikasi Anda (satu file properti per bahasa). Ini juga lebih mudah untuk mengubah pesan kesalahan, dan tidak perlu kompilasi ulang dari sumber Java.
Pada proyek saya, umumnya saya memiliki antarmuka yang berisi kode kesalahan (String atau integer, tidak terlalu peduli), yang berisi kunci dalam file properti untuk kesalahan ini:
di file properti:
Masalah lain dengan solusi Anda adalah pemeliharaan: Anda hanya memiliki 2 kesalahan, dan sudah 12 baris kode. Jadi bayangkan file Enumerasi Anda ketika Anda akan memiliki ratusan kesalahan untuk dikelola!
sumber
Overloading toString () tampaknya agak menjijikkan - yang tampaknya sedikit berlebihan dari penggunaan normal toString ().
Bagaimana dengan:
tampak jauh lebih bersih bagiku ... dan tidak terlalu bertele-tele.
sumber
Di pekerjaan terakhir saya, saya membahas lebih dalam versi enum:
@Error, @Info, @Warning dipertahankan dalam file kelas dan tersedia saat runtime. (Kami juga memiliki beberapa anotasi lain untuk membantu menjelaskan pengiriman pesan)
@Teks adalah anotasi waktu kompilasi.
Saya menulis pemroses anotasi untuk ini yang melakukan hal berikut:
Saya menulis beberapa rutinitas utilitas yang membantu mencatat kesalahan, membungkusnya sebagai pengecualian (jika diinginkan) dan sebagainya.
Saya mencoba membuat mereka mengizinkan saya membukanya ... - Scott
sumber
Saya merekomendasikan agar Anda melihat java.util.ResourceBundle. Anda harus peduli tentang I18N, tetapi itu sepadan meskipun tidak. Eksternalisasi pesan adalah ide yang sangat bagus. Saya telah menemukan bahwa sangat berguna untuk dapat memberikan spreadsheet kepada orang-orang bisnis yang memungkinkan mereka untuk menggunakan bahasa yang tepat seperti yang mereka ingin lihat. Kami menulis tugas Ant untuk menghasilkan file .properties pada waktu kompilasi. Itu membuat I18N sepele.
Jika Anda juga menggunakan Spring, jauh lebih baik. Kelas MessageSource mereka berguna untuk hal-hal semacam ini.
sumber
Hanya untuk terus mencambuk kuda mati khusus ini- kami telah menggunakan kode kesalahan numerik dengan baik ketika kesalahan ditunjukkan kepada pelanggan akhir, karena mereka sering lupa atau salah membaca pesan kesalahan yang sebenarnya tetapi kadang-kadang dapat mempertahankan dan melaporkan nilai numerik yang dapat memberikan Anda petunjuk tentang apa yang sebenarnya terjadi.
sumber
Ada banyak cara untuk mengatasinya. Pendekatan pilihan saya adalah memiliki antarmuka:
Sekarang Anda dapat menentukan sejumlah enum yang menyediakan pesan:
Sekarang Anda memiliki beberapa opsi untuk mengubahnya menjadi String. Anda dapat mengompilasi string ke dalam kode Anda (menggunakan anotasi atau parameter konstruktor enum) atau Anda dapat membacanya dari file config / properti atau dari tabel database atau campuran. Yang terakhir adalah pendekatan yang saya sukai karena Anda akan selalu membutuhkan beberapa pesan yang dapat Anda ubah menjadi teks sejak awal (mis. Saat Anda terhubung ke database atau membaca konfigurasi).
Saya menggunakan pengujian unit dan kerangka kerja refleksi untuk menemukan semua jenis yang mengimplementasikan antarmuka saya untuk memastikan setiap kode digunakan di suatu tempat dan bahwa file konfigurasi berisi semua pesan yang diharapkan, dll.
Menggunakan kerangka kerja yang dapat mengurai Java seperti https://github.com/javaparser/javaparser atau yang dari Eclipse , Anda bahkan dapat memeriksa di mana enum digunakan dan menemukan yang tidak digunakan.
sumber
Saya (dan tim kami lainnya di perusahaan saya) lebih memilih untuk memberikan pengecualian daripada mengembalikan kode kesalahan. Kode kesalahan harus diperiksa di mana-mana, diedarkan, dan cenderung membuat kode tidak dapat dibaca ketika jumlah kode menjadi lebih besar.
Kelas kesalahan kemudian akan menentukan pesannya.
PS: dan sebenarnya juga peduli dengan internasionalisasi!
PPS: Anda juga dapat mendefinisikan ulang metode kenaikan dan menambahkan logging, pemfilteran, dll. Jika diperlukan (setidaknya di lingkungan, di mana kelas Exception dan teman dapat diperpanjang / diubah)
sumber
Sedikit terlambat tetapi, saya hanya mencari solusi yang bagus untuk diri saya sendiri. Jika Anda memiliki jenis kesalahan pesan yang berbeda, Anda dapat menambahkan pabrik pesan kustom sederhana sehingga Anda dapat menentukan lebih banyak detail dan format yang Anda inginkan nanti.
EDIT: ok, menggunakan enum di sini sedikit berbahaya karena Anda mengubah enum tertentu secara permanen. Saya kira lebih baik mengganti ke kelas dan menggunakan bidang statis, tetapi Anda tidak dapat menggunakan '==' lagi. Jadi saya rasa itu adalah contoh yang baik tentang apa yang tidak boleh dilakukan, (atau melakukannya hanya selama inisialisasi) :)
sumber
enum untuk kode kesalahan / definisi pesan masih merupakan solusi yang bagus meskipun memiliki masalah i18n. Sebenarnya kita mungkin memiliki dua situasi: kode / pesan ditampilkan kepada pengguna akhir atau integrator sistem. Untuk kasus selanjutnya, I18N tidak diperlukan. Saya pikir layanan web kemungkinan besar adalah kasus selanjutnya.
sumber
Menggunakan
interface
sebagai konstanta pesan umumnya merupakan ide yang buruk. Ini akan bocor ke program klien secara permanen sebagai bagian dari API yang diekspor. Siapa tahu, programmer klien nanti mungkin mengurai pesan kesalahan itu (publik) sebagai bagian dari program mereka.Anda akan terkunci selamanya untuk mendukung ini, karena perubahan dalam format string akan / dapat merusak program klien.
sumber
Silakan ikuti contoh di bawah ini:
};
Dalam kode Anda, sebut seperti:
sumber
Saya menggunakan PropertyResourceBundle untuk menentukan kode kesalahan dalam aplikasi perusahaan untuk mengelola sumber daya kode kesalahan lokal. Ini adalah cara terbaik untuk menangani kode kesalahan daripada menulis kode (mungkin berlaku untuk beberapa kode kesalahan) bila jumlah kode kesalahan sangat besar dan terstruktur.
Lihat dokumen java untuk informasi lebih lanjut tentang PropertyResourceBundle
sumber