Catatan : Saya sedang mengerjakan versi 2 panduan ini dan saya membutuhkan bantuan Anda! Silakan gunakan formulir ini untuk memberi saya masukan tentang apa yang menurut Anda harus dilakukan pada versi berikutnya. Terima kasih!
Java adalah salah satu bahasa pemrograman paling populer, tetapi sepertinya tidak ada yang senang menggunakannya. Ya, Java sebenarnya adalah bahasa pemrograman yang bagus, dan sejak Java 8 dirilis baru-baru ini, saya memutuskan untuk menyusun daftar perpustakaan, praktik, dan alat untuk menjadikan penggunaan Java lebih baik. "Lebih baik" itu subjektif, jadi saya sarankan mengambil bagian yang sesuai dengan Anda dan menggunakannya, daripada mencoba menggunakan semuanya sekaligus. Jangan ragu untuk mengirimkan permintaan tarik yang menyarankan penambahan.
Artikel ini awalnya diposting di blog saya.
Baca ini dalam bahasa lain: Inggris, 简体中文
Secara tradisional, Java diprogram dengan gaya JavaBean perusahaan yang sangat bertele-tele. Gaya baru ini jauh lebih bersih, lebih tepat, dan enak dipandang.
Salah satu hal paling sederhana yang kita sebagai programmer lakukan adalah menyebarkan data. Cara tradisional untuk melakukan ini adalah dengan mendefinisikan JavaBean:
public class DataHolder {
private String data ;
public DataHolder () {
}
public void setData ( String data ) {
this . data = data ;
}
public String getData () {
return this . data ;
}
}
Ini bertele-tele dan boros. Meskipun IDE Anda secara otomatis menghasilkan kode ini, itu sia-sia. Jadi, jangan lakukan ini.
Sebaliknya, saya lebih suka gaya penulisan kelas C struct yang hanya menyimpan data:
public class DataHolder {
public final String data ;
public DataHolder ( String data ) {
this . data = data ;
}
}
Ini adalah pengurangan setengah jumlah baris kode. Lebih jauh lagi, kelas ini tidak dapat diubah kecuali Anda memperluasnya, jadi kita dapat mempertimbangkannya dengan lebih mudah karena kita tahu bahwa kelas ini tidak dapat diubah.
Jika Anda menyimpan objek seperti Peta atau Daftar yang dapat dimodifikasi dengan mudah, Anda sebaiknya menggunakan ImmutableMap atau ImmutableList, yang dibahas di bagian tentang kekekalan.
Jika Anda memiliki objek yang agak rumit yang ingin Anda buatkan strukturnya, pertimbangkan pola Builder.
Anda membuat kelas dalam statis yang akan membuat objek Anda. Ia menggunakan keadaan yang bisa berubah, tetapi segera setelah Anda memanggil build, ia akan mengeluarkan objek yang tidak dapat diubah.
Bayangkan kita memiliki DataHolder yang lebih rumit. Pembuatnya mungkin terlihat seperti:
public class ComplicatedDataHolder {
public final String data ;
public final int num ;
// lots more fields and a constructor
public static class Builder {
private String data ;
private int num ;
public Builder data ( String data ) {
this . data = data ;
return this ;
}
public Builder num ( int num ) {
this . num = num ;
return this ;
}
public ComplicatedDataHolder build () {
return new ComplicatedDataHolder ( data , num ); // etc
}
}
}
Kemudian untuk menggunakannya:
final ComplicatedDataHolder cdh = new ComplicatedDataHolder . Builder ()
. data ( "set this" )
. num ( 523 )
. build ();
Ada contoh Builder yang lebih baik di tempat lain, tetapi ini akan memberi Anda gambaran seperti apa. Ini berakhir dengan banyak boilerplate yang kami coba hindari, tetapi ini memberi Anda objek yang tidak dapat diubah dan antarmuka yang sangat lancar.
Daripada membuat objek pembangun dengan tangan, pertimbangkan untuk menggunakan salah satu dari banyak perpustakaan yang dapat membantu Anda menghasilkan pembangun.
Jika Anda membuat banyak objek yang tidak dapat diubah dengan tangan, pertimbangkan untuk menggunakan pemroses anotasi untuk menghasilkannya dari antarmuka secara otomatis. Hal ini meminimalkan kode boilerplate, mengurangi kemungkinan bug, dan meningkatkan kekekalan. Lihat presentasi ini untuk diskusi menarik tentang beberapa masalah dengan pola pengkodean Java normal.
Beberapa perpustakaan pembuatan kode yang bagus adalah yang tidak dapat diubah, nilai otomatis Google, dan Lombok.
Pengecualian yang dicentang harus digunakan dengan hati-hati, jika memang ada. Mereka memaksa pengguna Anda untuk menambahkan banyak blok coba/tangkap dan menggabungkan pengecualian Anda dengan miliknya sendiri. Lebih baik membuat pengecualian Anda memperluas RuntimeException saja. Hal ini memungkinkan pengguna Anda untuk menangani pengecualian Anda sesuai keinginan mereka, daripada memaksa mereka untuk menangani/mendeklarasikan bahwa pengecualian tersebut muncul setiap saat, sehingga mencemari kode.
Salah satu trik yang bagus adalah dengan memasukkan RuntimeExceptions ke dalam deklarasi throws metode Anda. Ini tidak berpengaruh pada kompiler, tetapi akan memberi tahu pengguna Anda melalui dokumentasi bahwa pengecualian ini dapat diberikan.
Ini lebih merupakan bagian rekayasa perangkat lunak daripada bagian Java, tetapi salah satu cara terbaik untuk menulis perangkat lunak yang dapat diuji adalah dengan menggunakan injeksi ketergantungan (DI). Karena Java sangat menganjurkan desain OO, untuk membuat perangkat lunak yang dapat diuji, Anda perlu menggunakan DI.
Di Java, hal ini biasanya dilakukan dengan Spring Framework. Ia memiliki pengkabelan berbasis kode atau pengkabelan berbasis konfigurasi XML. Jika Anda menggunakan konfigurasi XML, penting bagi Anda untuk tidak menggunakan Spring secara berlebihan karena format konfigurasinya yang berbasis XML. Seharusnya tidak ada logika atau struktur kontrol dalam XML. Itu seharusnya hanya memasukkan dependensi.
Alternatif yang baik untuk menggunakan Spring adalah perpustakaan Dagger Google dan Square atau Panduan Google. Mereka tidak menggunakan format file konfigurasi XML Spring, melainkan memasukkan logika injeksi ke dalam anotasi dan kode.
Cobalah untuk menghindari penggunaan nulls bila Anda bisa. Jangan mengembalikan koleksi nol padahal Anda seharusnya mengembalikan koleksi kosong. Jika Anda akan menggunakan null, pertimbangkan anotasi @Nullable. IntelliJ IDEA memiliki dukungan bawaan untuk anotasi @Nullable.
Baca selengkapnya tentang mengapa tidak menggunakan null di Kesalahan terburuk dalam ilmu komputer.
Jika Anda menggunakan Java 8, Anda dapat menggunakan tipe Opsional baru yang luar biasa. Jika suatu nilai mungkin ada atau tidak, bungkuslah dalam kelas Opsional seperti ini:
public class FooWidget {
private final String data ;
private final Optional < Bar > bar ;
public FooWidget ( String data ) {
this ( data , Optional . empty ());
}
public FooWidget ( String data , Optional < Bar > bar ) {
this . data = data ;
this . bar = bar ;
}
public Optional < Bar > getBar () {
return bar ;
}
}
Jadi sekarang jelas bahwa data tidak akan pernah nol, tetapi bar mungkin ada atau tidak. Opsional memiliki metode seperti isPresent , yang mungkin membuat Anda merasa tidak banyak perbedaan dari sekadar memeriksa null . Tapi itu memungkinkan Anda untuk menulis pernyataan seperti:
final Optional < FooWidget > fooWidget = maybeGetFooWidget ();
final Baz baz = fooWidget . flatMap ( FooWidget :: getBar )
. flatMap ( BarWidget :: getBaz )
. orElse ( defaultBaz );
Yang jauh lebih baik daripada dirantai jika pemeriksaan nol. Satu-satunya kelemahan menggunakan Opsional adalah perpustakaan standar tidak memiliki dukungan Opsional yang baik, jadi penanganan null masih diperlukan di sana.
Kecuali Anda memiliki alasan bagus untuk mengubahnya, variabel, kelas, dan koleksi tidak boleh diubah.
Variabel dapat dibuat tidak dapat diubah dengan final :
final FooWidget fooWidget ;
if ( condition ()) {
fooWidget = getWidget ();
} else {
try {
fooWidget = cachedFooWidget . get ();
} catch ( CachingException e ) {
log . error ( "Couldn't get cached value" , e );
throw e ;
}
}
// fooWidget is guaranteed to be set here
Sekarang Anda dapat yakin bahwa fooWidget tidak akan dipindahkan secara tidak sengaja. Kata kunci terakhir berfungsi dengan blok if/else dan dengan blok coba/tangkap. Tentu saja, jika fooWidget itu sendiri tidak dapat diubah, Anda dapat dengan mudah mengubahnya.
Koleksi harus, bila memungkinkan, menggunakan kelas Guava ImmutableMap, ImmutableList, atau ImmutableSet. Ini memiliki pembuat sehingga Anda dapat membangunnya secara dinamis dan kemudian menandainya sebagai tidak dapat diubah dengan memanggil metode build.
Kelas harus dibuat tidak dapat diubah dengan mendeklarasikan bidang tidak dapat diubah (melalui final ) dan dengan menggunakan koleksi yang tidak dapat diubah. Secara opsional, Anda dapat menjadikan kelas itu sendiri final sehingga tidak dapat diperluas dan diubah.
Berhati-hatilah jika Anda menambahkan banyak metode ke kelas Util.
public class MiscUtil {
public static String frobnicateString ( String base , int times ) {
// ... etc
}
public static void throwIfCondition ( boolean condition , String msg ) {
// ... etc
}
}
Kelas-kelas ini, pada awalnya, tampak menarik karena metode yang diterapkan di dalamnya tidak cocok untuk diterapkan di satu tempat saja. Jadi Anda memasukkan semuanya ke sini atas nama penggunaan kembali kode.
Obatnya lebih buruk dari penyakitnya. Tempatkan kelas-kelas ini di tempatnya dan lakukan refaktorisasi secara agresif. Jangan beri nama kelas, paket, atau pustaka dengan nama yang terlalu umum, seperti "MiscUtils" atau "ExtrasLibrary". Hal ini mendorong pembuangan kode yang tidak terkait di sana.
Pemformatan jauh lebih penting daripada yang dibayangkan kebanyakan programmer. Apakah konsistensi menunjukkan bahwa Anda peduli dengan keahlian Anda dan apakah itu membantu orang lain membaca? Sangat. Namun jangan buang waktu seharian untuk menambahkan spasi pada blok if agar "cocok".
Jika Anda benar-benar membutuhkan panduan pemformatan kode, saya sangat merekomendasikan panduan Java Style dari Google. Bagian terbaik dari panduan itu adalah bagian Praktik Pemrograman. Pasti layak untuk dibaca.
Mendokumentasikan kode yang dilihat pengguna Anda adalah penting. Dan ini berarti menggunakan contoh dan menggunakan deskripsi variabel, metode, dan kelas yang masuk akal.
Konsekuensi dari hal ini adalah tidak mendokumentasikan apa yang tidak perlu didokumentasikan. Jika Anda tidak punya apa-apa untuk dikatakan tentang argumen tersebut, atau jika sudah jelas, jangan dokumentasikan argumen tersebut. Dokumentasi boilerplate lebih buruk daripada tidak ada dokumentasi sama sekali, karena ini menipu pengguna Anda agar berpikir bahwa ada dokumentasi.
Java 8 memiliki aliran yang bagus dan sintaksis lambda. Anda bisa menulis kode seperti ini:
final List < String > filtered = list . stream ()
. filter ( s -> s . startsWith ( "s" ))
. map ( s -> s . toUpperCase ())
. collect ( Collectors . toList ());
Alih-alih ini:
final List < String > filtered = new ArrayList <>();
for ( String str : list ) {
if ( str . startsWith ( "s" ) {
filtered . add ( str . toUpperCase ());
}
}
Hal ini memungkinkan Anda menulis kode dengan lebih lancar, sehingga lebih mudah dibaca.
Menyebarkan Java dengan benar bisa jadi sedikit rumit. Ada dua cara utama untuk menerapkan Java saat ini: menggunakan kerangka kerja atau menggunakan solusi buatan sendiri yang lebih fleksibel.
Karena menerapkan Java tidaklah mudah, kerangka kerja telah dibuat yang dapat membantu. Dua yang terbaik adalah Dropwizard dan Spring Boot. Kerangka kerja Play juga dapat dianggap sebagai salah satu kerangka penerapan ini.
Semuanya mencoba menurunkan hambatan untuk mengeluarkan kode Anda. Mereka sangat membantu jika Anda baru mengenal Java atau jika Anda perlu menyelesaikan sesuatu dengan cepat. Penerapan JAR tunggal lebih mudah daripada penerapan WAR atau EAR yang rumit.
Namun, mereka bisa jadi agak tidak fleksibel dan agak berpendirian keras, jadi jika proyek Anda tidak sesuai dengan pilihan yang dibuat oleh pengembang kerangka kerja Anda, Anda harus bermigrasi ke konfigurasi yang lebih sederhana.
Alternatif yang bagus : Gradle.
Maven masih menjadi alat standar untuk membangun, mengemas, dan menjalankan pengujian Anda. Ada alternatif lain, seperti Gradle, tetapi penerapannya tidak sama seperti yang dimiliki Maven. Jika Anda baru mengenal Maven, Anda harus memulai dengan Maven dengan Contoh.
Saya ingin memiliki root POM dengan semua dependensi eksternal yang ingin Anda gunakan. Ini akan terlihat seperti ini. Root POM ini hanya memiliki satu ketergantungan eksternal, tetapi jika produk Anda cukup besar, Anda akan memiliki lusinan. Root POM Anda harus berupa proyek tersendiri: dalam kontrol versi dan dirilis seperti proyek Java lainnya.
Jika menurut Anda memberi tag POM root untuk setiap perubahan ketergantungan eksternal terlalu berlebihan, Anda tidak membuang waktu seminggu untuk melacak kesalahan ketergantungan lintas proyek.
Semua proyek Maven Anda akan menyertakan root POM Anda dan semua informasi versinya. Dengan cara ini, Anda mendapatkan versi setiap ketergantungan eksternal yang dipilih perusahaan Anda, dan semua plugin Maven yang benar. Jika Anda perlu menarik dependensi eksternal, cara kerjanya seperti ini:
< dependencies >
< dependency >
< groupId >org.third.party</ groupId >
< artifactId >some-artifact</ artifactId >
</ dependency >
</ dependencies >
Jika Anda menginginkan ketergantungan internal, itu harus dikelola oleh masing-masing proyek bagian. Kalau tidak, akan sulit untuk menjaga nomor versi root POM tetap waras.
Salah satu bagian terbaik tentang Java adalah banyaknya perpustakaan pihak ketiga yang melakukan segalanya. Pada dasarnya setiap API atau toolkit memiliki Java SDK dan mudah untuk menggunakannya dengan Maven.
Dan perpustakaan Java itu sendiri bergantung pada versi tertentu dari perpustakaan lain. Jika Anda menggunakan cukup banyak perpustakaan, Anda akan mendapatkan konflik versi, yaitu seperti ini:
Foo library depends on Bar library v1.0
Widget library depends on Bar library v0.9
Versi mana yang akan dimasukkan ke dalam proyek Anda?
Dengan plugin konvergensi ketergantungan Maven, build akan error jika dependensi Anda tidak menggunakan versi yang sama. Kemudian, Anda memiliki dua opsi untuk menyelesaikan konflik tersebut:
Pilihan mana yang akan dipilih bergantung pada situasi Anda: jika Anda ingin melacak versi satu proyek, maka pengecualian adalah hal yang masuk akal. Di sisi lain, jika Anda ingin menjelaskannya secara eksplisit, Anda dapat memilih versinya, meskipun Anda harus memperbaruinya saat memperbarui dependensi lainnya.
Jelas Anda memerlukan semacam server integrasi berkelanjutan yang akan terus membangun versi SNAPSHOT Anda dan pembuatan tag berdasarkan git tag.
Jenkins dan Travis-CI adalah pilihan yang wajar.
Cakupan kode berguna, dan Cobertura memiliki plugin Maven dan dukungan CI yang bagus. Ada alat cakupan kode lain untuk Java, tapi saya telah menggunakan Cobertura.
Anda memerlukan tempat untuk meletakkan JAR, WAR, dan EAR yang Anda buat, sehingga Anda memerlukan repositori.
Pilihan umum adalah Artifactory dan Nexus. Keduanya berfungsi, dan memiliki pro dan kontra masing-masing.
Anda harus memiliki instalasi Artifactory/Nexus Anda sendiri dan mencerminkan dependensi Anda ke dalamnya. Ini akan menghentikan kerusakan build Anda karena beberapa repositori Maven hulu tidak berfungsi.
Jadi sekarang kode Anda sudah dikompilasi, repositori Anda sudah disiapkan, dan Anda perlu mengeluarkan kode Anda di lingkungan pengembangan dan akhirnya mendorongnya ke produksi. Jangan berhemat di sini, karena mengotomatisasi ini akan menghasilkan keuntungan untuk waktu yang lama.
Chef, Puppet, dan Ansible adalah pilihan yang khas. Saya telah menulis sebuah alternatif bernama Skuadron, yang menurut saya tentu saja harus Anda periksa karena lebih mudah untuk melakukannya dengan benar daripada alternatif lainnya.
Apa pun alat yang Anda pilih, jangan lupa untuk mengotomatiskan penerapan Anda.
Mungkin fitur terbaik tentang Java adalah banyaknya perpustakaan yang dimilikinya. Ini adalah kumpulan kecil perpustakaan yang mungkin dapat diterapkan pada kelompok orang terbesar.
Pustaka standar Java, yang dulunya merupakan langkah maju yang luar biasa, kini sepertinya kehilangan beberapa fitur utama.
Proyek Apache Commons memiliki banyak perpustakaan yang berguna.
Commons Codec memiliki banyak metode pengkodean/dekode yang berguna untuk string Base64 dan hex. Jangan buang waktu Anda untuk menulis ulang itu.
Commons Lang adalah perpustakaan masuk untuk manipulasi dan pembuatan String, kumpulan karakter, dan banyak metode utilitas lainnya.
Commons IO memiliki semua metode terkait File yang Anda inginkan. Ia memiliki FileUtils.copyDirectory, FileUtils.writeStringToFile, IOUtils.readLines dan banyak lagi.
Guava adalah perpustakaan terbaik Google yang berisi Java-is-missing. Hampir sulit untuk menyaring semua yang saya suka tentang perpustakaan ini, tapi saya akan mencobanya.
Cache adalah cara sederhana untuk mendapatkan cache dalam memori yang dapat digunakan untuk menyimpan cache akses jaringan, akses disk, fungsi memoize, atau apa pun juga. Cukup terapkan CacheBuilder yang memberi tahu Guava cara membuat cache dan Anda sudah siap!
Koleksi yang tidak dapat diubah . Ada banyak di antaranya: ImmutableMap, ImmutableList, atau bahkan ImmutableSortedMultiSet jika itu gaya Anda.
Saya juga suka menulis koleksi yang bisa berubah dengan cara Guava:
// Instead of
final Map < String , Widget > map = new HashMap <>();
// You can use
final Map < String , Widget > map = Maps . newHashMap ();
Ada kelas statis untuk Daftar, Peta, Kumpulan, dan lainnya. Mereka lebih bersih dan lebih mudah dibaca.
Jika Anda terjebak dengan Java 6 atau 7, Anda bisa menggunakan kelas Collections2, yang memiliki metode seperti filter dan transformasi. Mereka memungkinkan Anda menulis kode dengan lancar tanpa dukungan aliran Java 8.
Guava juga memiliki hal-hal sederhana, seperti Joiner yang menggabungkan string pada pemisah dan kelas untuk menangani interupsi dengan mengabaikannya.
Pustaka Gson Google adalah pustaka penguraian JSON yang sederhana dan cepat. Cara kerjanya seperti ini:
final Gson gson = new Gson ();
final String json = gson . toJson ( fooWidget );
final FooWidget newFooWidget = gson . fromJson ( json , FooWidget . class );
Sangat mudah dan menyenangkan untuk diajak bekerja sama. Panduan pengguna Gson memiliki lebih banyak contoh.
Salah satu gangguan saya dengan Java adalah tidak adanya tupel yang terpasang di perpustakaan standar. Untungnya, proyek tupel Java memperbaikinya.
Mudah digunakan dan berfungsi dengan baik:
Pair < String , Integer > func ( String input ) {
// something...
return Pair . with ( stringResult , intResult );
}
Javaslang adalah perpustakaan fungsional, yang dirancang untuk menambahkan fitur-fitur yang hilang yang seharusnya menjadi bagian dari Java 8. Beberapa fitur ini adalah
Ada beberapa perpustakaan Java yang bergantung pada koleksi Java asli. Ini dibatasi agar tetap kompatibel dengan kelas yang dibuat dengan fokus berorientasi objek dan dirancang agar bisa berubah. Koleksi Javaslang untuk Java benar-benar baru, terinspirasi oleh Haskell, Clojure, dan Scala. Mereka dibuat dengan fokus fungsional dan mengikuti desain yang tidak dapat diubah.
Kode seperti ini secara otomatis aman untuk thread dan bebas coba-coba:
// Success/Failure containing the result/exception
public static Try < User > getUser ( int userId ) {
return Try . of (() -> DB . findUser ( userId ))
. recover ( x -> Match . of ( x )
. whenType ( RemoteException . class ). then ( e -> ...)
. whenType ( SQLException . class ). then ( e -> ...));
}
// Thread-safe, reusable collections
public static List < String > sayByeBye () {
return List . of ( "bye, " bye ", "collect" , "mania" )
. map ( String :: toUpperCase )
. intersperse ( " " );
}
Joda-Time adalah perpustakaan waktu terbaik yang pernah saya gunakan. Sederhana, lugas, mudah diuji. Apa lagi yang bisa Anda minta?
Anda hanya memerlukan ini jika Anda belum menggunakan Java 8, karena ia memiliki perpustakaan waktu baru yang tidak buruk.
Lombok adalah perpustakaan yang menarik. Melalui anotasi, ini memungkinkan Anda mengurangi boilerplate yang sangat diderita oleh Java.
Ingin setter dan getter untuk variabel kelas Anda? Sederhana:
public class Foo {
@ Getter @ Setter private int var ;
}
Sekarang Anda dapat melakukan ini:
final Foo foo = new Foo ();
foo . setVar ( 5 );
Dan masih banyak lagi. Saya belum pernah menggunakan Lombok dalam produksinya, namun saya tidak sabar untuk segera menggunakannya.
Alternatif bagus : Jersey atau Spark
Ada dua kubu utama untuk melakukan layanan web RESTful di Java: JAX-RS dan yang lainnya.
JAX-RS adalah cara tradisional. Anda menggabungkan anotasi dengan antarmuka dan implementasi untuk membentuk layanan web menggunakan sesuatu seperti Jersey. Apa yang menyenangkan tentang ini adalah Anda dapat dengan mudah membuat klien hanya dari kelas antarmuka.
Kerangka kerja Play adalah pandangan yang sangat berbeda tentang layanan web di JVM: Anda memiliki file rute dan kemudian Anda menulis kelas yang direferensikan dalam rute tersebut. Ini sebenarnya merupakan keseluruhan kerangka kerja MVC, tetapi Anda dapat dengan mudah menggunakannya hanya untuk layanan web REST.
Ini tersedia untuk Java dan Scala. Ini sedikit menderita karena Scala-first, tapi masih bagus untuk digunakan di Java.
Jika Anda terbiasa dengan kerangka mikro seperti Flask dengan Python, Spark akan sangat familiar. Ini bekerja sangat baik dengan Java 8.
Ada banyak solusi logging Java di luar sana. Favorit saya adalah SLF4J karena sangat pluggable dan dapat menggabungkan log dari banyak kerangka logging yang berbeda secara bersamaan. Punya proyek aneh yang menggunakan java.util.logging, JCL, dan log4j? SLF4J cocok untuk Anda.
Manual dua halaman sudah cukup untuk memulai.
Saya tidak suka kerangka ORM yang berat karena saya suka SQL. Jadi saya menulis banyak template JDBC dan pemeliharaannya agak sulit. jOOQ adalah solusi yang jauh lebih baik.
Ini memungkinkan Anda menulis SQL di Java dengan cara yang aman:
// Typesafely execute the SQL statement directly with jOOQ
Result < Record3 < String , String , String >> result =
create . select ( BOOK . TITLE , AUTHOR . FIRST_NAME , AUTHOR . LAST_NAME )
. from ( BOOK )
. join ( AUTHOR )
. on ( BOOK . AUTHOR_ID . equal ( AUTHOR . ID ))
. where ( BOOK . PUBLISHED_IN . equal ( 1948 ))
. fetch ();
Dengan menggunakan ini dan pola DAO, Anda dapat mempermudah akses database.
Pengujian sangat penting untuk perangkat lunak Anda. Paket-paket ini membantu mempermudahnya.
Alternatif yang bagus : TestNG.
junit tidak perlu diperkenalkan. Ini adalah alat standar untuk pengujian unit di Java.
Namun Anda mungkin tidak menggunakan jUnit secara maksimal. jUnit mendukung pengujian berparametri, aturan untuk menghentikan Anda menulis begitu banyak boilerplate, teori untuk menguji kode tertentu secara acak, dan asumsi.
Jika Anda telah melakukan injeksi ketergantungan, inilah hasilnya: meniru kode yang memiliki efek samping (seperti berbicara dengan server REST) dan tetap menegaskan perilaku kode yang memanggilnya.
jMock adalah alat tiruan standar untuk Java. Ini terlihat seperti ini:
public class FooWidgetTest {
private Mockery context = new Mockery ();
@ Test
public void basicTest () {
final FooWidgetDependency dep = context . mock ( FooWidgetDependency . class );
context . checking ( new Expectations () {{
oneOf ( dep ). call ( with ( any ( String . class )));
atLeast ( 0 ). of ( dep ). optionalCall ();
}});
final FooWidget foo = new FooWidget ( dep );
Assert . assertTrue ( foo . doThing ());
context . assertIsSatisfied ();
}
}
Ini menyiapkan FooWidgetDependency melalui jMock dan kemudian menambahkan ekspektasi. Kami berharap metode panggilan dep akan dipanggil satu kali dengan beberapa String dan metode opsionalCall dep akan dipanggil nol kali atau lebih.
Jika Anda harus mengatur ketergantungan yang sama berulang-ulang, Anda mungkin harus memasukkannya ke dalam perlengkapan pengujian dan memasukkan menegaskanIsSatisfied dalam perlengkapan @After .
Apakah Anda pernah melakukan ini dengan junit?
final List < String > result = some . testMethod ();
assertEquals ( 4 , result . size ());
assertTrue ( result . contains ( "some result" ));
assertTrue ( result . contains ( "some other result" ));
assertFalse ( result . contains ( "shouldn't be here" ));
Ini hanya boilerplate yang menjengkelkan. AssertJ memecahkan masalah ini. Anda dapat mengubah kode yang sama menjadi ini:
assertThat ( some . testMethod ()). hasSize ( 4 )
. contains ( "some result" , "some other result" )
. doesNotContain ( "shouldn't be here" );
Antarmuka yang lancar ini membuat pengujian Anda lebih mudah dibaca. Apa lagi yang Anda inginkan?
Alternatif bagus : Eclipse dan Netbeans
IDE Java terbaik adalah IntelliJ IDEA. Ia memiliki banyak sekali fitur luar biasa, dan merupakan hal utama yang membuat verbositas Java dapat dipahami. Pelengkapan otomatis sangat bagus, pemeriksaannya terbaik, dan alat pemfaktoran ulang sangat membantu.
Edisi komunitas gratis cukup baik bagi saya, tetapi ada banyak fitur hebat di edisi Ultimate seperti alat database, dukungan Spring Framework, dan Chronon.
Salah satu fitur favorit saya di GDB 7 adalah kemampuan untuk melakukan perjalanan kembali ke masa lalu saat melakukan debug. Hal ini dimungkinkan dengan plugin Chronon IntelliJ saat Anda mendapatkan edisi Ultimate.
Anda mendapatkan riwayat variabel, langkah mundur, riwayat metode, dan banyak lagi. Agak aneh untuk menggunakannya pertama kali, tetapi ini dapat membantu men-debug beberapa bug yang sangat rumit, Heisenbugs, dan sejenisnya.
Alternatif yang bagus : DCEVM
Integrasi berkelanjutan sering kali menjadi tujuan produk perangkat lunak sebagai layanan. Bagaimana jika Anda bahkan tidak perlu menunggu hingga build selesai untuk melihat perubahan kode secara langsung?
Itulah yang dilakukan JRebel. Setelah Anda menghubungkan server Anda ke klien JRebel, Anda dapat melihat perubahan di server Anda secara instan. Ini adalah penghematan waktu yang sangat besar jika Anda ingin bereksperimen dengan cepat.
Sistem tipe Java cukup lemah. Itu tidak membedakan antara Strings dan Strings yang sebenarnya merupakan ekspresi reguler, juga tidak melakukan pemeriksaan noda. Namun, Checker Framework melakukan hal ini dan lebih banyak lagi.
Ia menggunakan anotasi seperti @Nullable untuk memeriksa jenis. Anda bahkan dapat menentukan anotasi Anda sendiri untuk membuat analisis statis menjadi lebih efektif.
Bahkan ketika mengikuti praktik terbaik, pengembang terbaik pun akan membuat kesalahan. Ada sejumlah alat di luar sana yang dapat Anda gunakan untuk memvalidasi kode Java guna mendeteksi masalah pada kode Anda. Di bawah ini adalah pilihan kecil dari beberapa alat yang paling populer. Banyak di antaranya terintegrasi dengan IDE populer seperti Eclipse atau IntelliJ yang memungkinkan Anda menemukan kesalahan dalam kode Anda lebih cepat.
Selain menggunakan alat-alat ini selama pengembangan, sering kali merupakan ide bagus untuk menjalankannya selama tahap pembangunan Anda. Mereka dapat diikat ke dalam alat pembangunan seperti Maven atau Gradle & juga ke dalam alat integrasi berkelanjutan.
Kebocoran memori terjadi, bahkan di Java. Untungnya, ada alat untuk itu. Alat terbaik yang saya gunakan untuk memperbaikinya adalah Eclipse Memory Analyzer. Dibutuhkan heap dump dan memungkinkan Anda menemukan masalahnya.
Ada beberapa cara untuk mendapatkan heap dump untuk proses JVM, tapi saya menggunakan jmap:
$ jmap -dump:live,format=b,file=heapdump.hprof -F 8152
Attaching to process ID 8152, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.25-b01
Dumping heap to heapdump.hprof ...
... snip ...
Heap dump file created
Kemudian Anda dapat membuka file heapdump.hprof dengan Memory Analyzer dan melihat apa yang terjadi dengan cepat.
Sumber daya untuk membantu Anda menjadi master Java.