Ringkasan singkat tentang praktik terbaik pengkodean Java

berdasarkan standar pengkodean oleh Oracle, Google, Twitter dan Kerangka Kerja Spring

Tujuan artikel ini adalah untuk memberi Anda ringkasan singkat tentang do dan donat dengan kata lain pilih dan hindari berdasarkan standar pengkodean dari raksasa teknologi seperti Oracle, Google, Twitter dan Kerangka Kerja Spring.

Anda mungkin atau mungkin tidak setuju dengan beberapa praktik terbaik yang disajikan di sini, dan itu benar-benar baik-baik saja selama ada beberapa standar pengkodean yang berlaku.

Mengapa standar pengkodean di tempat pertama? Ada banyak alasan bagus jika Anda Google dan saya akan meninggalkan Anda dengan ilustrasi berikut

Dokumen standar pengkodean bisa panjang dan membosankan. Artikel ini mengambil sedikit demi sedikit dari konvensi pengkodean oleh Google, Oracle, Twitter dan Spring dan tujuannya adalah untuk memberi Anda serangkaian praktik yang mudah diikuti dan tidak membosankan untuk membuat kode Anda mudah dibaca dan dipelihara.

Hampir selalu Anda akan bergabung dengan tim yang mengerjakan perangkat lunak yang ada dan ada peluang yang cukup bagus bahwa sebagian besar penulis telah meninggalkan atau beralih ke proyek yang berbeda, membuat Anda terdampar dengan bagian-bagian kode yang membuat Anda mempertanyakan kemanusiaan.

Mari selami praktik terbaik dari berbagai standar pengkodean.

File Sumber Java

Berikut ini dianggap sebagai praktik terbaik ketika datang ke file sumber java:

  • Panjang file sumber lebih rendah dari 2.000 baris kode
  • File sumber diatur dengan komentar dokumentasi, deklarasi paket, diikuti oleh komentar kelas, impor dikelompokkan (statis terakhir), kelas / antarmuka tanda tangan dan sebagainya seperti yang ditunjukkan di bawah ini
paket com.example.model;
/ **
 * Perspektif bebas implementasi untuk dibaca oleh pengembang
 * yang mungkin belum tentu memiliki kode sumber
 *
 * @author x, y, z
 * @tanggal
 * @versi
 * @hak cipta
 *
 * /
impor com.example.util.FileUtil;
/ *
 * Komentar spesifik kelas opsional
 *
 * /
kelas publik SomeClass {
  // Variabel statis dalam urutan visibilitas
  Integer akhir publik statis PUBLIC_COUNT = 1;
  Integer akhir statis PROTECTED_COUNT = 1;
  Integer akhir privat statis PRIVATE_COUNT = 1;
  // Variabel Instance dalam urutan visibilitas
  nama String publik;
  String kode pos;
  alamat String pribadi;
  // Pembuat dan kelebihan beban dalam urutan berurutan
  SomeClass publik () {}
  SomeClass publik (nama String) {
    this.name = nama;
  }
  // Metode
  public String doSomethingUseful () {
    mengembalikan "Sesuatu yang bermanfaat";
  }
  // getter, setter, equals, hashCode dan toString di akhir
}

Penamaan

Nama kelas dan antarmuka adalah CamelCase dan disarankan untuk menggunakan seluruh kata dan menghindari akronim / singkatan. Misalnya kelas Raster atau kelas ImageSprite

  • Paket - nama com.deepspace di atas com.deepSpace atau com.deep_space
  • Nama file adalah CamelCase dan diakhiri dengan .java yang cocok dengan nama kelas. Ada satu kelas publik per file dengan masing-masing kelas tingkat atas dalam file-nya
  • Metode - nama harus berupa kata kerja dalam huruf campuran dengan setiap kata internal ditulis dengan huruf besar misalnya run (); atau runFast ();
  • Konstanta - harus huruf besar dengan “_” memisahkan setiap kata misalnya int MIN_WIDTH = 44; dan int MAX_WIDTH = 99;
  • Variabel - nama yang memberi tahu pembaca program apa yang diwakili oleh variabel tersebut, yaitu jika Anda menyimpan nilai tes, lalu pilih kelas vs var1. Simpan nama variabel yang singkat, termasuk metadata.
// Lebih suka () - nama variabel pendek dan jelaskan apa yang disimpannya
int schoolId;
int [] filteredSchoolIds;
int [] uniqueSchooldIds;
Peta  usersById;
Nilai string;
// Hindari (x) - Penamaan variabel terlalu rinci
int schoolIdentificationNumber;
int [] userProvidedSchoolIds;
int [] schoolIdsAfterRemovingDuplicates;
Peta  idToUserMap;
String valueString;

Ingat - nama variabel harus pendek dan mudah memberi tahu pembaca nilai apa yang diwakilinya. Gunakan penilaian Anda.

Lebih suka & Hindari

Memformat dan indentasi adalah tentang mengatur kode Anda agar mudah dibaca, dan itu termasuk spasi, panjang garis, wraps dan break dan sebagainya

  • Lekukan - Gunakan 2 atau 4 spasi dan tetap konsisten
  • Panjang garis - Hingga 70 hingga 120 karakter tergantung pada pengaruhnya pada keterbacaan. Penting untuk menghilangkan kebutuhan untuk pengguliran horizontal dan menempatkan jeda baris setelah koma dan operator.

Metode - Berikut adalah daftar praktik terbaik

// Lebih suka () Istirahat baris arbitrer dan putus setelah koma.
String downloadAnternet (internet internet, tabung tabung,
    Blogosphere blog, Jumlah  bandwidth) {
  tubes.download (internet);
}
// Hindari (x) Argumen metode sulit dibedakan dengan tubuh metode
String downloadAnternet (internet internet, tabung tabung,
    Blogosphere blog, Jumlah  bandwidth) {
    tubes.download (internet);
}
// Lebih suka () Tambahkan 8 (dua kali 2 atau 4) spasi untuk indentasi dalam
private horkingLongMethodName statis yang disinkronkan (int anArg,
        Obyek anotherArg, String yetAnotherArg,
        Object andStillAnother) {
  ...
}
// Lebih suka () Pemindaian mudah dan ruang kolom tambahan.
public String downloadAnternet (
    Internet internet,
    Tabung tabung,
    Blogosphere blog,
    Jumlah  bandwidth) {
  tubes.download (internet);
  ...
}
Tes unit akan menangkap itu

Jika-cek - IMO menulis kode yang diformat dengan baik memudahkan untuk menemukan kesalahan ketik dan kesalahan kepada penulis dan peninjau kode, lihat di bawah:

// Hindari (x) Jangan hilangkan {}
jika (kondisi)
  pernyataan;
// Hindari (x)
jika (x <0) negatif (x);
// Hindari (x)
if (a == b && c == d) {
...
}
// Lebih suka ()
if ((a == b) && (c == d)) {
...
}
// Lebih suka ()
if (kondisi) {
  pernyataan;
} lain jika (kondisi) {
  pernyataan;
} lain jika (kondisi) {
  pernyataan;
}
// Hindari (x)
jika ((kondisi1 && kondisi2)
    || (kondisi3 && kondisi4)
    ||! (condition5 && condition6)) {// BAD WRAPS
    doSomethingAboutIt (); // MEMBUAT GARIS INI MUDAH DILAKUKAN
}
// Lebih suka ()
jika ((kondisi1 && kondisi2)
        || (kondisi3 && kondisi4)
        ||! (condition5 && condition6)) {
    doSomethingAboutIt ();
}

Operator ternary - Dan di bawah ini adalah praktik yang disarankan

alpha = (aLongBooleanExpression)? beta: gamma;
alpha = (aLongBooleanExpression)? beta
        : gamma;
alpha = (aLongBooleanExpression)
        ? beta
        : gamma;

Switch - Ketika datang untuk beralih itu praktik terbaik untuk

  • Selalu memiliki case standar bahkan tanpa kode
  • Gunakan / * jatuh melalui * / untuk menunjukkan kontrol jatuh ke kasus berikutnya
switch (kondisi) {
  case ABC:
    pernyataan;
  / * jatuh *
  kasus DEF:
    pernyataan;
    istirahat;
  default:
    pernyataan;
     istirahat;
}

Pesan pengecualian - Saat melempar pengecualian di sini adalah contoh pesan yang bagus dan buruk.

// Hindari (x) - Tidak mudah dibaca
buang IllegalStateException baru ("Gagal memproses permintaan" + request.getId ()
    + "untuk pengguna" + user.getId () + "query: '" + query.getText ()
    + "'");
// Lebih suka () - Cukup mudah dibaca
melempar IllegalStateException baru ("Gagal memproses"
    + "permintaan" + request.getId ()
    + "untuk pengguna" + user.getId ()
    + "kueri: '" + kueri.getText () + "'");

Iterator dan Streaming - Streaming menjadi lebih umum dan terkadang sangat kompleks, penting untuk membuat indentasi agar mudah dibaca.

// Hindari (x) - Tidak mudah dibaca
Modul  Iterable = ImmutableList.  builder (). Add (LifecycleModule baru ())
    .add (AppLauncherModule ()) baru. addAll (application.getModules ()). build ();
// Lebih suka () - Cukup mudah dibaca
Modul  yang dapat diubah = ImmutableList.  builder ()
    .add (LifecycleModule baru ())
    .add (AppLauncherModule baru ())
    .addAll (application.getModules ())
    .membangun();
Cukup ikuti standar pengkodean - benar-benar ada

Deklarasi dan Tugas— Satu deklarasi per baris direkomendasikan karena mendorong komentar seperti yang ditunjukkan di bawah ini.

// Lebih suka ()
tingkat int; // tingkat indentasi
int sizeMeter; // ukuran meja
// Hindari (x) yang mendukung hal di atas
tingkat int, sizeMeter;
// Lebih suka () - Sertakan unit dalam nama atau tipe variabel
pollIntervalMs yang panjang;
int fileSizeGb;
Jumlah  fileSize;
// Hindari (x) jenis pencampuran
int foo, fooarray [];
// Hindari (x) - Jangan pisahkan dengan koma
Format.print (System.out, "error"), keluar (1);
// Hindari (x) beberapa tugas
fooBar.fChar = barFoo.lchar = 'c';
// Hindari (x) tugas yang disematkan dalam upaya meningkatkan kinerja // atau menyimpan satu baris. Saya bersalah melakukan ini :(
d = (a = b + c) + r;
// Lebih suka () di atas
a = b + c;
d = a + r;
// Lebih suka ()
String [] args
// Hindari (x)
String args []
// Lebih suka () Gunakan lama "L" bukan "l" untuk menghindari kebingungan dengan 1
batas waktu yang lama = 3000000000L;
// Hindari (x) - Sulit untuk mengatakan huruf terakhir adalah l dan bukan 1
batas waktu yang lama = 3000000000l;

Letakkan deklarasi hanya di awal blok (Blok adalah kode yang dikelilingi oleh kurung kurawal {dan}). Jangan menunggu untuk mendeklarasikan variabel sampai digunakan pertama kali; itu dapat membingungkan programmer yang tidak waspada dan menghambat portabilitas kode dalam ruang lingkup.

// Lebih suka () mendeklarasikan di awal blok.
kekosongan publik doSomething () {
  int whatIRepresent; // awal blok metode
  if (kondisi) {
    int someFlag; // awal dari blok "jika"
    ...
  }
}

Penting juga untuk menghindari deklarasi lokal yang menyembunyikan deklarasi dari level yang lebih tinggi dan untuk menghindari kebingungan seperti yang ditunjukkan di bawah ini

int count;
...
kekosongan publik doSomething () {
  if (kondisi) {
    int count; // HINDARI!
    ...
  }
  ...
}

Penjarangan spasi & jeda baris - Hindari godaan untuk menyimpan 1-2 baris kode dengan mengorbankan keterbacaan. Berikut ini semua praktik terbaik dalam hal spasi dan garis kosong (Ruang putih memang membuat perbedaan)

  • Satu (1) baris kosong antara metode dan pengembang Spring merekomendasikan dua (2) baris kosong setelah konstruktor, blok statis, bidang, dan kelas dalam
  • Operator space pad yaitu. Gunakan int foo = a + b + 1; lebih dari int foo = a + b + 1;
  • Pisahkan semua operator biner kecuali "." Dari operan menggunakan spasi
  • Buka kurung “{” muncul di akhir baris yang sama dengan pernyataan deklarasi atau metode dan kurung tutup “}” memulai garis dengan sendirinya diindentasi
// Lebih suka () - Spasi setelah "sementara" dan sebelum "("
while (true) {
  ...
}
// Hindari (x) - Tidak seperti di atas tanpa spasi
while (true) {
  ...
}
// Lebih suka () - Tidak ada ruang antara "doSomething" dan "("
kekosongan publik doSomething () {
  ...
}
// Hindari (x) - Tidak seperti ruang di atas
kekosongan publik doSomething () {
  ...
}
// Lebih suka () - Tambahkan spasi setelah argumen
public void doSomething (int a, int b) {
  ...
}
// Lebih suka () - Ruang antara operan dan operator (mis. +, =)
a + = c + d;
a = (a + b) / (c * d);
while (d ++ = s ++) {
  n ++;
}

Dokumentasi dan Komentar

Patut disebutkan bahwa hampir semua kode mengalami perubahan sepanjang masa pakainya dan akan ada saat-saat ketika Anda atau seseorang mencoba mencari tahu apa yang harus dilakukan oleh blok kode, metode, atau kelas yang rumit kecuali dijelaskan dengan jelas. Kenyataannya hampir selalu sebagai berikut

Ada kalanya komentar pada potongan kode yang kompleks, metode, kelas tidak menambah nilai atau melayani tujuannya. Ini biasanya terjadi ketika berkomentar demi hal itu.

Komentar harus digunakan untuk memberikan ikhtisar kode dan memberikan informasi tambahan yang tidak tersedia dalam kode itu sendiri. Mari kita mulai. Ada dua jenis komentar

Komentar Implementasi - dimaksudkan untuk mengomentari kode atau komentar tentang implementasi kode tertentu.

Komentar Dokumentasi - dimaksudkan untuk menggambarkan spesifikasi kode dari perspektif bebas implementasi untuk dibaca oleh pengembang yang mungkin belum tentu memiliki kode sumber.

Frekuensi komentar terkadang mencerminkan kualitas kode yang buruk. Ketika Anda merasa harus menambahkan komentar, pertimbangkan menulis ulang kode untuk membuatnya lebih jelas.

Jenis Komentar Implementasi

Ada empat (4) jenis komentar implementasi seperti yang ditunjukkan di bawah ini

  • Blokir komentar - lihat contoh di bawah
  • Komentar satu baris - ketika komentar tidak lebih dari satu baris
  • Komentar tambahan - Komentar yang sangat singkat dipindahkan ke ujung kanan
  • Komentar akhir baris - memulai komentar yang berlanjut ke baris baru. Itu dapat mengomentari baris lengkap atau hanya sebagian baris. Seharusnya tidak digunakan pada beberapa baris berturut-turut untuk komentar teks; Namun, ini dapat digunakan dalam beberapa baris berturut-turut untuk mengomentari bagian kode.
// Blokir komentar
/ *
 * Penggunaan: Memberikan deskripsi file, metode, struktur data
 * dan algoritma. Dapat digunakan di awal setiap file dan
 * sebelum setiap metode. Digunakan untuk komentar panjang yang tidak sesuai a
 * garis tunggal. 1 Baris kosong untuk melanjutkan setelah blok komentar.
 * /
// Komentar satu baris
if (kondisi) {
 / * Tangani kondisinya. * /
  ...
}
// Komentar tertinggal
if (a == 2) {
 mengembalikan TRUE; /* kasus spesial */
} lain {
 return isPrime (a); / * hanya berfungsi untuk ganjil * /
}
// Komentar akhir baris
if (foo> 1) {
  // Lakukan double-flip.
  ...
} lain {
  return false; // Jelaskan mengapa di sini.
}
// if (bar> 1) {
//
// // Lakukan tiga kali lipat.
// ...
//}
//lain
// kembalikan salah;

Komentar dokumentasi (mis. Javadoc)

Javadoc adalah alat yang menghasilkan dokumentasi HTML dari kode java Anda menggunakan komentar yang dimulai dengan / ** dan diakhiri dengan * / - lihat Wikipedia untuk detail lebih lanjut tentang cara kerja Javadoc atau hanya membaca bersama.

Berikut ini contoh Javadoc

/ **
 * Mengembalikan objek Gambar yang kemudian dapat dilukis di layar.
 * Argumen url harus menentukan {@link URL} absolut. Nama
 * argumen adalah specifier yang relatif terhadap argumen url.
 * 

 * Metode ini selalu kembali segera, apakah atau tidak  * gambar ada. Ketika applet ini mencoba untuk menggambar  * Layar, data akan dimuat. Grafik primitiiv. Răspunde.,.,. .Pdf -  * Gambar yang menggambar akan secara bertahap melukis di layar.  *  * @param url URL absolut yang memberikan lokasi dasar gambar  * @param beri nama lokasi gambar, relatif terhadap argumen url  * @ kembalikan gambar pada URL yang ditentukan  * @lihat Gambar  * /  getImage Gambar publik (URL url, String name) {         coba {             return getImage (URL baru (url, nama));         } catch (MalformedURLException e) {             kembali nol;         }  }

Dan di atas akan menghasilkan HTML sebagai berikut ketika javadoc dijalankan terhadap kode yang memiliki di atas

Lihat di sini untuk lebih lanjut

Berikut adalah beberapa tag kunci yang dapat Anda gunakan untuk meningkatkan kualitas dokumentasi java yang dihasilkan.

@author => @author Raf
@code => {@code A  C}
@deprecated => @deprecated deprecation-message
@exception => @exception IOException dilemparkan ketika
@link => {@link package.class # label anggota}
@param => @param deskripsi nama-parameter
@return => Metode apa yang dikembalikan
@see => @see "string" ATAU @see  
@since => Untuk menunjukkan versi ketika metode yang dapat diakses publik ditambahkan

Untuk daftar lengkap dan deskripsi lebih rinci lihat di sini

Standar pengodean Twitter menyarankan agar jangan menggunakan tag @author

Kode dapat berpindah tangan berkali-kali dalam masa pakainya, dan cukup sering penulis asli file sumber tidak relevan setelah beberapa iterasi. Kami merasa lebih baik untuk mempercayai riwayat komit dan file PEMILIK untuk menentukan kepemilikan tubuh kode.

Berikut ini adalah contoh bagaimana Anda dapat menulis komentar dokumentasi yang berwawasan seperti yang dijelaskan dalam standar pengkodean Twitter

// Buruk.
// - Doc tidak mengatakan apa-apa bahwa deklarasi metode tidak.
// - Ini adalah 'filler doc'. Itu akan melewati pemeriksaan gaya, tapi
tidak membantu siapa pun.
/ **
 * Membagi string.
 *
 * @param s string.
 * @return Daftar string.
 * /
Daftar  split (String s);
// Lebih baik.
// - Kita tahu metode apa yang digunakan.
// - Masih beberapa perilaku yang tidak terdefinisi.
/ **
 * Memisahkan string di spasi putih.
 *
 * @param s String untuk dipisah. String {@code null} diperlakukan sebagai string kosong.
 * @return Daftar daftar input yang dibatasi spasi-putih.
 * /
Daftar  split (String s);
// Bagus.
// - Meliputi lagi tepi case.
/ **
 * Memisahkan string di spasi putih. Karakter spasi putih berulang
 * diciutkan
 *
 * @param s String untuk dipisah. String {@code null} diperlakukan sebagai string kosong.
 * @return Daftar daftar input yang dibatasi spasi-putih.
 * /
Daftar  split (String s);

Penting untuk menjadi profesional ketika menulis komentar

// Hindari (x)
// Aku sangat membenci xml / sabun, mengapa itu tidak bisa melakukan ini untukku !?
coba {
  userId = Integer.parseInt (xml.getField ("id"));
} catch (NumberFormatException e) {
  ...
}
// Lebih suka ()
// TODO (Jim): Tuck validasi bidang di perpustakaan.
coba {
  userId = Integer.parseInt (xml.getField ("id"));
} catch (NumberFormatException e) {
  ...
}

Dan penting untuk diingat untuk tidak mendokumentasikan metode yang ditimpa kecuali pelaksanaannya telah berubah.

Dan berikut adalah beberapa hal yang perlu diingat

  • Hindari impor wildcard - seperti yang dijelaskan dalam standar pengkodean Twitter, ini membuat sumber kelas kurang jelas. Saya bekerja dalam tim dengan campuran pengguna Eclipse dan IntelliJ dan saya menemukan bahwa Eclipse menghapus impor wildcard dan IntelliJ memperkenalkannya. Mungkin ada opsi untuk mematikannya, hanya ingin menunjukkan default untuk keduanya.
  • Selalu gunakan @Override anotasi saat mengesampingkan
  • Dorong penggunaan @Nullable saat bidang atau metode mengembalikan nol
  • Manfaatkan komentar khusus untuk pekerjaan di masa depan dan jangan lupa untuk meninggalkan referensi untuk diri Anda sendiri sehingga orang lain tahu siapa yang mengajukan pertanyaan Y mereka alih-alih menebak, menghapusnya atau memeriksa git menyalahkan untuk menemukan siapa yang menambahkannya. Beberapa IDE seperti Eclipse dan IntelliJ juga membantu dalam daftar ini untuk akses mudah dan pengingat.
// FIXME (Raf): Pesan yang dapat ditindaklanjuti menjelaskan apa yang perlu dilakukan
// TODO (Raf): Pesan yang dapat ditindaklanjuti menggambarkan apa yang perlu dilakukan

Permainan akhirnya adalah menulis kode yang memudahkan kehidupan penulis dan pengelola masa depan.

Game terakhir

Bahan bacaan lain yang relevan

Daftar artikel yang relevan yang relevan dengan penulisan kode yang bersih, terstruktur dengan baik, mudah dibaca dan dikelola. Jika Anda ingin membaca lebih lanjut, rekomendasikan yang berikut ini

dan daftar tips lain yang baik untuk menulis kode bersih