CodeGym /Java Blog /Acak /Aturan Pengkodean: Kekuatan Nama yang Benar, Komentar Bai...
John Squirrels
Level 41
San Francisco

Aturan Pengkodean: Kekuatan Nama yang Benar, Komentar Baik dan Buruk

Dipublikasikan di grup Acak
Aturan Pengkodean: Kekuatan Nama yang Benar, Komentar Baik dan Buruk - 1Seberapa sering Anda harus menggali kode orang lain? Alih-alih dua jam, Anda mungkin menghabiskan dua hari untuk sekadar memahami logika dari apa yang terjadi. Lucunya, bagi orang yang menulis kode, semuanya jelas dan sepenuhnya transparan. Ini tidak mengherankan: lagipula, kode yang sempurna adalah konsep yang sangat kabur, karena setiap pengembang memiliki visi sendiri tentang dunia dan kode juga. Lebih dari sekali saya berada dalam situasi ketika seorang rekan kerja dan saya melihat kode yang sama dan memiliki pendapat berbeda tentang kebenaran dan kebersihannya.Aturan pengkodean: kekuatan nama yang benar, komentar baik dan buruk - 2Kedengarannya akrab, bukan? Namun, ada beberapa prinsip yang telah teruji waktu yang harus dipatuhi. Pada akhirnya, mereka akan menguntungkan Anda, karena jika Anda membiarkan kode Anda dalam keadaan di mana Anda sendiri ingin menerimanya, maka dunia akan menjadi sedikit lebih bahagia dan lebih bersih. Di artikel kami sebelumnya(atau lebih tepatnya, panduan kecil) tentang aturan pengkodean, kami mendapat sedikit rekomendasi untuk menulis sistem secara keseluruhan dan bagian-bagian penyusunnya, seperti objek, antarmuka, kelas, metode, dan variabel. Di artikel yang sama, saya dengan santai menyebutkan penamaan yang benar untuk elemen tertentu. Saya ingin membicarakannya hari ini, karena nama yang benar membuat kode lebih mudah dibaca. Kami akan menutup topik kode yang benar dengan beberapa refleksi, contoh kecil komentar dalam kode, dan pertimbangan apakah ini bagus atau tidak. Baiklah, mari kita mulai.

Nama yang benar

Nama yang benar meningkatkan keterbacaan kode, sehingga mengurangi waktu yang diperlukan untuk membiasakan diri Anda dengan kode, karena menggunakan metode jauh lebih mudah ketika namanya menjelaskan fungsinya secara kasar. Segala sesuatu dalam kode terdiri dari nama (variabel, metode, kelas, objek, file, dll.), jadi poin ini menjadi sangat penting saat membuat kode yang benar dan bersih. Berdasarkan hal di atas, nama harus menyampaikan makna, misalnya mengapa variabel itu ada, apa fungsinya, dan bagaimana penggunaannya. Saya akan mencatat lebih dari sekali bahwa komentar terbaik untuk sebuah variabel adalah memberinya nama yang bagus.Aturan pengkodean: kekuatan nama yang benar, komentar baik dan buruk - 3

dari serial TV "Sherlock" (2010-2017)

Penamaan antarmuka

Antarmuka biasanya memiliki nama yang dimulai dengan huruf kapital dan ditulis dalam CamelCase. Saat menulis antarmuka, biasanya dianggap praktik yang baik untuk menambahkan awalan "I" untuk menetapkannya sebagai antarmuka (misalnya, IUserService), tetapi itu terlihat sangat jelek dan mengganggu. Dalam kasus seperti itu, lebih baik menghilangkan awalan (UserService) dan menambahkan "Impl" sebagai akhiran pada nama implementasinya (mis. UserServiceImpl). Atau mungkin, sebagai upaya terakhir, tambahkan awalan "C" pada nama implementasi (misalnya CUserService).

Nama kelas

Sama seperti antarmuka, nama kelas dikapitalisasi dan menggunakan CamelCase. Tidak masalah jika kita menghadapi kiamat zombie, tidak masalah jika akhirnya sudah dekat - tidak pernah, tidak pernah, tidak boleh nama kelas menjadi kata kerja! Nama kelas dan objek harus berupa kata benda atau kata benda majemuk (UserController, UserDetails, UserAccount, dan seterusnya). Anda tidak boleh menempelkan singkatan aplikasi ke akhir nama setiap kelas, karena itu hanya akan menambah kerumitan yang tidak perlu. Misalnya, jika kita memiliki aplikasi Migrasi Data Pengguna, maka jangan tambahkan "UDM" ke setiap kelas, yaitu UDMUserDetails, UDMUserAccount, UDMUserController.

Nama metode

Biasanya, nama metode dimulai dengan huruf kecil, tetapi mereka juga menggunakan gaya huruf unta (camelCase). Di atas, kami mengatakan bahwa nama kelas tidak boleh berupa kata kerja. Di sini situasinya justru sebaliknya: nama metode harus berupa kata kerja atau frasa kata kerja: findUserById, findAllUsers, createUser, dan sebagainya. Saat membuat metode (serta variabel dan kelas), jadi gunakan konvensi penamaan yang konsisten untuk menghindari kebingungan. Misalnya, untuk menemukan pengguna, metode dapat diberi nama getUserById atau findUserById. Dan satu hal lagi: jangan gunakan humor atas nama metode, karena orang lain mungkin tidak mengerti lelucon itu. Akibatnya, mereka mungkin gagal memahami apa yang dilakukan metode tersebut.

Nama variabel

Dalam kebanyakan kasus, nama variabel dimulai dengan huruf kecil dan juga menggunakan huruf unta, kecuali jika variabelnya adalah konstanta global. Dalam kasus seperti itu, semua huruf dari nama ditulis dalam huruf besar dan kata dipisahkan dengan garis bawah ("_"). Untuk kenyamanan, Anda dapat menggunakan konteks yang bermakna saat memberi nama variabel. Dengan kata lain, ketika sebuah variabel ada sebagai bagian dari sesuatu yang lebih besar, misalnya, firstName, lastName, atau status. Dalam kasus seperti itu, Anda dapat menambahkan awalan yang menunjukkan objek tempat variabel ini berada. Misalnya: userFirstName, userLastName, userStatus. Anda juga harus menghindari nama yang mirip untuk variabel ketika mereka memiliki arti yang sama sekali berbeda. Berikut adalah beberapa antonim yang sering ditemui yang digunakan dalam nama variabel:
  • mulai/akhir
  • pertama/terakhir
  • terkunci/tidak terkunci
  • min/maks
  • selanjutnya/sebelumnya
  • lama/baru
  • dibuka/ditutup
  • terlihat / tidak terlihat
  • sumber/sasaran
  • sumber tujuan
  • atas/bawah

Nama variabel pendek

Ketika kita memiliki variabel seperti x atau n atau sesuatu seperti itu, kita tidak langsung melihat maksud dari orang yang menulis kode tersebut. Tidak jelas apa yang dilakukan n. Mencari tahu itu membutuhkan perenungan yang lebih hati-hati (dan ini berarti waktu, waktu, waktu). Misalnya, kita memiliki bidang yang mewakili id ​​dari pengguna yang bertanggung jawab. Alih-alih beberapa nama variabel seperti x atau hanya id, kami akan menamai variabel ini "responsibleUserId", yang segera meningkatkan keterbacaan dan konten informasi. Yang mengatakan, nama pendek seperti n memiliki tempat sebagai variabel lokal dalam metode kecil, di mana blok kode yang melibatkan variabel ini hanya beberapa baris, dan nama metode dengan sempurna menggambarkan apa yang terjadi di sana. Melihat variabel seperti itu, pengembang memahami bahwa itu adalah kepentingan sekunder dan memiliki cakupan yang sangat terbatas. Akibatnya, ruang lingkup memiliki ketergantungan tertentu pada panjang nama variabel: semakin panjang nama, semakin global variabelnya dan sebaliknya. Sebagai contoh, inilah metode untuk menemukan pengguna yang terakhir disimpan berdasarkan tanggal:

public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("No user exists"));
}
Di sini kami menggunakan variabel bernama pendek x dan y untuk mengurutkan aliran, dan kemudian kami melupakannya.

Panjang optimal

Mari lanjutkan dengan topik panjang nama. Panjang nama yang optimal adalah antara n dan maximumNumberOfUsersInTheCurrentGroup. Dengan kata lain, nama pendek mengalami kekurangan makna, sedangkan nama yang terlalu panjang memperpanjang program tanpa menambah keterbacaan, dan kita terlalu malas untuk menulisnya setiap saat. Terlepas dari kasus yang dijelaskan di atas untuk variabel dengan nama pendek seperti n, Anda harus tetap menggunakan panjang sekitar 8-16 karakter. Ini bukan aturan ketat, hanya pedoman.

Perbedaan kecil

Saya tidak bisa tidak menyebutkan perbedaan halus dalam nama. Ini juga merupakan praktik yang buruk, karena perbedaan ini dapat membingungkan atau memerlukan banyak waktu ekstra untuk menyadarinya. Misalnya, perbedaan antara InvalidDataAccessApiUsageException dan InvalidDataAccessResourceUsageException sulit dikenali secara sekilas. Kebingungan juga sering muncul saat menggunakan huruf kecil L dan O, karena mereka dapat dengan mudah disalahartikan sebagai 1 dan 0. Pada beberapa font perbedaannya lebih jelas, pada beberapa font lebih sedikit.

Artinya

Kita perlu membuat nama yang bermakna, tetapi tidak menciptakan ambiguitas melalui sinonim, karena, misalnya, UserData dan UserInfo sebenarnya memiliki arti yang sama. Dalam hal ini, kita harus menggali kode lebih dalam untuk memahami objek tertentu yang kita butuhkan. Hindari kata-kata yang tidak menyampaikan informasi bermanfaat. Misalnya, di firstNameString, mengapa kita membutuhkan kata String? Mungkinkah ini benar-benar objek Tanggal? Tentu saja tidak. Jadi, kami cukup menggunakan firstName. Saya juga ingin menyebutkan variabel boolean. Sebagai contoh, ambil boolean bernama flagDeleted. Kata bendera tidak memiliki arti. Lebih masuk akal untuk menyebutnya Dihapus.

Disinformasi

Saya juga ingin menyampaikan beberapa patah kata tentang konvensi penamaan yang salah. Katakanlah kita memiliki variabel bernama userActivityList, tetapi alih-alih menjadi Daftar, objek ini adalah jenis wadah lain atau objek penyimpanan khusus. Ini bisa membingungkan programmer rata-rata: lebih baik menyebutnya sesuatu seperti userActivityGroup atau userActivities.

Mencari

Salah satu kelemahan dari nama pendek dan sederhana adalah sulit ditemukan dalam kumpulan kode yang besar — ​​Mana yang lebih mudah ditemukan: "nama" atau "NAME_FOR_DEFAULT_USER"? Opsi kedua, tentu saja. Kita harus menghindari kata (huruf) yang sering ditemui dalam nama, karena hanya akan menambah jumlah file yang cocok selama pencarian, yang tidak baik. Saya ingin mengingatkan Anda bahwa pemrogram menghabiskan lebih banyak waktu untuk membaca kode daripada menulisnya, jadi cerdaslah dalam menamai elemen aplikasi Anda. Tetapi bagaimana jika nama yang baik tidak dapat ditemukan? Bagaimana jika nama suatu metode tidak menggambarkan fungsinya dengan baik? Di sinilah komentar memasuki panggung.

Komentar

Aturan pengkodean: kekuatan nama yang benar, komentar baik dan buruk - 4Tidak ada yang lebih baik daripada komentar yang relevan, tetapi tidak ada yang mengacaukan modul seperti komentar yang kosong, usang, atau salah. Mereka bisa menjadi pedang bermata dua, bukan? Tetap saja, Anda tidak boleh memperlakukan komentar sebagai sesuatu yang sangat baik, melainkan sebagai sesuatu yang kurang jahat. Lagi pula, komentar pada dasarnya adalah cara untuk mengkompensasi pemikiran yang tidak muncul dengan jelas dalam kode. Misalnya, kami menggunakannya untuk menyampaikan esensi suatu metode, jika metode itu sendiri ternyata terlalu membingungkan. Dalam situasi ini, lebih baik memfaktorkan ulang kode dengan benar daripada menulis catatan deskriptif. Semakin tua komentarnya, semakin buruk komentarnya, karena kode cenderung tumbuh dan berkembang, tetapi komentar mungkin tetap sama. Semakin banyak waktu yang telah berlalu sejak komentar dibuat, semakin dipertanyakan. Komentar yang tidak akurat jauh lebih buruk daripada tidak ada komentar sama sekali, karena membingungkan dan menipu, memberikan harapan yang salah. Dan bahkan jika kita memiliki kode yang sangat rumit, kita harus menulis ulang daripada mengomentarinya.

Jenis komentar

  • Komentar hukum — Komentar di awal setiap file sumber karena alasan hukum, misalnya:

    
    * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
    * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
    

  • Komentar informatif — Komentar yang mewakili penjelasan kode (memberikan informasi tambahan atau menguraikan maksud dari bagian kode yang diberikan).

    Misalnya:

    
    /*
    * Combines the user from the database with the one passed for updating
    * When a field in requestUser is empty, it is filled with old data from foundUser
    */
    private User mergeUser(User requestUser, User foundUser) {
           return new User(
           foundUser.getId(),
           requestUser.getFirstName() == null ? requestUser.getFirstName() : foundUser.getFirstName(),
           requestUser.getMiddleName() == null ? requestUser.getMiddleName() : foundUser.getMiddleName(),
           requestUser.getLastName() == null ? requestUser.getLastName() : foundUser.getLastName(),
           requestUser.getAge() == null ? requestUser.getAge() : foundUser.getAge()
           );
           }
    

    Dalam hal ini, Anda dapat melakukannya tanpa komentar, karena nama metode dan parameternya, ditambah dengan fungsionalitas yang sangat transparan, menggambarkan dirinya dengan baik.

  • Komentar peringatan — Komentar dimaksudkan untuk memperingatkan pengembang lain tentang konsekuensi yang tidak diinginkan dari suatu tindakan (misalnya, memperingatkan mereka tentang mengapa tes ditandai sebagai @Ignore):

    
    // Takes too long to run
    // Don't run if you don't have a lot of time
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
    

  • TODO — Komentar yang merupakan catatan tentang sesuatu yang perlu dilakukan di masa depan yang tetapi karena alasan tertentu tidak dapat dilakukan sekarang. Ini adalah praktik yang baik, tetapi komentar semacam itu harus ditinjau secara berkala untuk menghapus komentar yang tidak relevan dan menghindari keruwetan.

    Contohnya adalah:

    
    // TODO: Add a check for the current user ID (when the security context is created)
    
    @Override
    public Resource downloadFile(File file) {
           return fileManager.download(file);
           }
    

    Di sini kami mencatat fakta bahwa kami perlu menambahkan perbandingan pengguna yang melakukan operasi pengunduhan (yang ID-nya akan kami ekstrak dari konteks keamanan) dengan pengguna yang melakukan operasi penyimpanan.

  • Memperkuat komentar — Komentar yang menekankan pentingnya suatu keadaan yang pada pandangan pertama mungkin tampak tidak penting.

    Sebagai contoh, pertimbangkan sebuah metode yang mengisi database pengujian dengan beberapa skrip:

    
    Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8)
           .trim()
           .split(";"))
           .forEach(jdbcTemplate::update);
    // The trim() call is very important. It removes possible spaces at the end of the script
    // so that when we read and split into separate requests, we don't end up with empty ones
    

  • Komentar Javadoc — Komentar yang menjelaskan API untuk fungsionalitas tertentu. Mungkin ada komentar yang paling berguna, karena API yang terdokumentasi jauh lebih mudah untuk digunakan. Yang mengatakan, mereka juga bisa ketinggalan zaman seperti jenis komentar lainnya. Jadi, jangan pernah lupa bahwa kontribusi utama dokumentasi dibuat bukan oleh komentar, tetapi oleh kode yang baik.

    Berikut adalah contoh metode yang cukup umum untuk memperbarui pengguna:

    
    /**
    * Updates the passed fields for a user based on its id.
         *
    * @param id id of the user to be updated
    * @param user user with populated fields for updating
    * @return updated user
    */
           User update(Long id, User user);
    

Komentar buruk

  • bergumam komentar - Komentar yang biasanya ditulis dengan tergesa-gesa dan yang artinya hanya dapat dipahami oleh pengembang yang menulisnya, karena hanya dia yang memahami situasi bernuansa yang dirujuk oleh komentar tersebut.

    Pertimbangkan contoh ini:

    
    public void configureSomeSystem() {
           try{
           String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE);
           FileInputStream stream = new FileInputStream(configPath);
           } catch (FileNotFoundException e) {
           // If there is no configuration file, the default configuration is loaded 
          }
    }
    

    Siapa yang memuat pengaturan ini? Apakah mereka sudah dimuat? Apakah metode ini seharusnya menangkap pengecualian dan memuat pengaturan default? Terlalu banyak pertanyaan muncul yang hanya bisa dijawab dengan menyelidiki bagian lain dari sistem.

  • Komentar yang berlebihan — Komentar yang tidak membawa beban semantik, karena apa yang terjadi di bagian kode tertentu sangat jelas. Dengan kata lain, komentar tidak lebih mudah dibaca daripada kodenya.

    Mari kita lihat contohnya:

    
    public class JdbcConnection{
    public class JdbcConnection{
       /**
        * The logger associated with the current class
        */
       private Logger log = Logger.getLogger(JdbcConnection.class.getName());
    
       /**
        * Creates and returns a connection using the input parameters
        */
       public static Connection buildConnection(String url, String login, String password, String driver) throws Exception {
           Class.forName(driver);
           connection = DriverManager.getConnection(url, login, password);
           log.info("Created connection with db");
           return connection;
       }
    

    Apa gunanya komentar seperti itu? Semua yang mereka jelaskan sudah sangat jelas.

  • Komentar yang tidak dapat diandalkan — Komentar yang tidak benar dan hanya menyesatkan (disinformasi). Sebagai contoh, inilah salah satunya.

    
    /**
    * Helper method. Closes the connection with the scanner if isNotUsing is true
    */
    private void scanClose(Scanner scan, boolean isNotUsing) throws Exception {
       if (!isNotUsing) {
           throw new Exception("The scanner is still in use");
       } scan.close();
    }
    

    Apa yang salah dengan komentar ini? Fakta bahwa itu sedikit berbohong kepada kami, bahwa koneksi ditutup jika isNotUsing salah, bukan sebaliknya, seperti yang diinformasikan oleh komentar kepada kami.

  • Komentar wajib — Komentar yang dianggap wajib (misalnya komentar Javadoc), tetapi sebenarnya terkadang menumpuk secara berlebihan dan tidak dapat diandalkan serta tidak perlu (Anda perlu memikirkan apakah komentar ini benar-benar diperlukan).

  • Contoh:

    
    /**
    * Create a user based on the parameters
    * @param firstName first name of the created user
    * @param middleName middle name of the created user
    * @param lastName last name of the created user
    * @param age age of the created user
    * @param address address of the created user
    * @return user that was created
    */
    User createNewUser(String firstName, String middleName, String lastName, String age, String address);
    

    Apakah Anda dapat memahami apa yang dilakukan metode ini tanpa komentar ini? Kemungkinan besar ya, jadi komentar menjadi tidak berguna di sini.

  • Komentar log — Komentar yang terkadang ditambahkan ke awal modul setiap kali diedit (sesuatu seperti log perubahan).

    
    /**
    * Records kept since January 9, 2020;
    **********************************************************************
    * 9 Jan 2020: Providing a database connection using JDBC Connection;
    * 15 Jan 2020: Adding DAO-level interfaces for working with the database;
    * 23 Jan 2020: Adding integration tests for the database;
    * 28 Jan 2020: Implementation of DAO-level interfaces;
    * 1 Feb 2020: Development of interfaces for services,
    * in accordance with the requirements specified in user stories;
    * 16 Feb 2020: Implementation of service interfaces
    * (implementation of business logic related to the work of the database);
    * 25 Feb 2020: Adding tests for services;
    * 8 Mar 2020: Celebration of International Women's Day (Terry is drunk again);
    * 21 Mar 2020: Refactoring the service layer;
    */
    

    Pendekatan ini pernah dibenarkan, tetapi dengan munculnya sistem kontrol versi (misalnya, Git), ini menjadi kekacauan dan kerumitan kode yang tidak perlu.

  • Komentar kepengarangan — Komentar yang tujuannya menunjukkan orang yang menulis kode, sehingga Anda dapat menghubunginya dan mendiskusikan bagaimana, apa, dan mengapa, misalnya:

    
    * @author Bender Bending
    

    Sekali lagi, sistem kontrol versi mengingat dengan tepat siapa yang menambahkan sedikit kode dan kapan, jadi pendekatan ini tidak berguna.

  • Kode yang dikomentari — Kode yang dikomentari karena satu dan lain alasan. Ini adalah salah satu kebiasaan terburuk, karena yang terjadi adalah Anda mengomentari sesuatu dan melupakannya, dan kemudian pengembang lain tidak berani menghapusnya (lagipula, bagaimana jika itu sesuatu yang berharga?).

    
    //    public void someMethod(SomeObject obj) {
    //    .....
    //    }
    

    Akibatnya, kode yang dikomentari terakumulasi seperti sampah. Dalam hal apa pun Anda tidak boleh meninggalkan kode seperti itu. Jika Anda benar-benar membutuhkannya, jangan lupakan sistem kontrol versinya.

  • Komentar yang tidak jelas — Komentar yang mendeskripsikan sesuatu dengan cara yang sangat rumit.

    
    /*
        * Start with an array large enough to store
        * all the data bytes (plus filter bytes) with a cushion, plus 300 bytes
        * for header data
        */
    this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
    

    Komentar harus menjelaskan kode. Seharusnya itu sendiri tidak membutuhkan penjelasan. Jadi apa yang salah di sini? Apa itu "filter byte"? Tentang apa "+1" itu? Mengapa tepatnya 300?

Jika Anda sudah memutuskan untuk menulis komentar, berikut adalah beberapa tips:
  1. Gunakan gaya yang mudah dipertahankan: mempertahankan gaya yang terlalu mewah dan eksotis itu menyebalkan dan menghabiskan waktu.
  2. Jangan gunakan komentar akhir baris yang mengacu pada satu baris: hasilnya adalah tumpukan komentar yang banyak. Terlebih lagi, sulit untuk memikirkan komentar yang berarti untuk setiap baris.
  3. Saat Anda menulis komentar, cobalah untuk menjawab pertanyaan "mengapa", bukan "bagaimana".
  4. Hindari informasi yang diringkas. Seperti yang saya katakan di atas, kita tidak memerlukan penjelasan untuk sebuah komentar: komentar itu sendiri adalah penjelasannya.
  5. Anda dapat menggunakan komentar untuk mencatat satuan dan rentang nilai.
  6. Tempatkan komentar di dekat kode yang dijelaskan.
Terakhir, saya masih ingin mengingatkan Anda bahwa komentar terbaik bukanlah komentar, melainkan penggunaan penamaan yang terampil di seluruh aplikasi Anda. Sebagai aturan, sebagian besar waktu kami akan bekerja dengan kode yang ada, memelihara dan mengembangkannya. Jauh lebih nyaman bila kode ini mudah dibaca dan dimengerti, karena kode yang buruk menjadi kendala. Ini seperti melempar kunci pas saat bekerja, dan tergesa-gesa adalah rekan setianya. Dan semakin banyak kode buruk yang kita miliki, semakin banyak penurunan kinerja. Ini berarti kita perlu melakukan refactor dari waktu ke waktu. Tetapi jika sejak awal Anda mencoba menulis kode yang tidak akan menyebabkan pengembang berikutnya ingin menemukan dan membunuh Anda, maka Anda tidak perlu terlalu sering memfaktorkannya kembali. Tetapi itu tetap diperlukan, karena kondisi dan persyaratan produk terus berubah dengan penambahan ketergantungan dan koneksi baru. Yah, saya kira itu saja untuk saya hari ini. Terima kasih kepada semua orang yang membaca sejauh ini :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION