

Nama yang betul
Nama yang betul meningkatkan kebolehbacaan kod, sekali gus mengurangkan masa yang diperlukan untuk membiasakan diri anda dengan kod, kerana menggunakan kaedah adalah lebih mudah apabila namanya secara kasar menggambarkan fungsinya. Segala-galanya dalam kod terdiri daripada nama (pembolehubah, kaedah, kelas, objek, fail, dll.), jadi perkara ini menjadi sangat penting apabila mencipta kod yang betul dan bersih. Berdasarkan perkara di atas, nama harus menyampaikan makna, contohnya, mengapa pembolehubah itu wujud, apa yang dilakukannya, dan bagaimana ia digunakan. Saya akan perhatikan lebih daripada sekali bahawa komen terbaik untuk pembolehubah adalah untuk memberikannya nama yang baik.
dari siri TV "Sherlock" (2010-2017)
Menamakan antara muka
Antara muka biasanya mempunyai nama yang bermula dengan huruf besar dan ditulis dalam CamelCase. Apabila menulis antara muka, ia pernah dianggap sebagai amalan yang baik untuk menambah awalan "I" untuk menetapkannya sebagai antara muka (contohnya, IUserService), tetapi itu kelihatan agak hodoh dan mengganggu. Dalam kes sedemikian, adalah lebih baik untuk meninggalkan awalan (UserService) dan menambah "Impl" sebagai akhiran kepada nama pelaksanaannya (cth. UserServiceImpl). Atau mungkin, sebagai pilihan terakhir, tambahkan awalan "C" pada nama pelaksanaan (cth CUserService).Nama kelas
Sama seperti antara muka, nama kelas menggunakan huruf besar dan menggunakan CamelCase. Tidak kira jika kita menghadapi kiamat zombi, tidak kira jika penghujungnya sudah dekat — jangan sekali-kali, jangan sekali-kali nama kelas menjadi kata kerja! Nama kelas dan objek mestilah kata nama atau kata nama majmuk (UserController, UserDetails, UserAccount, dan sebagainya). Anda tidak sepatutnya meletakkan singkatan aplikasi pada hujung nama setiap kelas, kerana itu hanya akan menambah kerumitan yang tidak perlu. Sebagai contoh, jika kami mempunyai aplikasi Migrasi Data Pengguna, maka sila jangan tambahkan "UDM" pada setiap kelas, iaitu UDMUserDetails, UDMUserAccount, UDMUserController.Nama kaedah
Biasanya, nama kaedah bermula dengan huruf kecil, tetapi mereka juga menggunakan gaya kes unta (camelCase). Di atas, kami berkata bahawa nama kelas tidak boleh menjadi kata kerja. Di sini keadaannya adalah sebaliknya: nama kaedah mestilah kata kerja atau frasa kata kerja: findUserById, findAllUsers, createUser dan sebagainya. Apabila mencipta kaedah (serta pembolehubah dan kelas), jadi gunakan konvensyen penamaan yang konsisten untuk mengelakkan kekeliruan. Sebagai contoh, untuk mencari pengguna, kaedah boleh dinamakan getUserById atau findUserById. Dan satu lagi: jangan gunakan jenaka dalam nama kaedah, kerana orang lain mungkin tidak memahami jenaka itu. Akibatnya, mereka mungkin gagal memahami apa yang dilakukan oleh kaedah itu.Nama boleh ubah
Dalam kebanyakan kes, nama pembolehubah bermula dengan huruf kecil dan juga menggunakan camelCase, kecuali apabila pembolehubah ialah pemalar global. Dalam kes sedemikian, semua huruf nama ditulis dalam huruf besar dan perkataan dipisahkan dengan garis bawah ("_"). Untuk kemudahan, anda boleh menggunakan konteks yang bermakna apabila menamakan pembolehubah. Dalam erti kata lain, apabila pembolehubah wujud sebagai sebahagian daripada sesuatu yang lebih besar, contohnya, firstName, lastName atau status. Dalam kes sedemikian, anda boleh menambah awalan yang menunjukkan objek yang menjadi milik pembolehubah ini. Contohnya: userFirstName, userLastName, userStatus. Anda juga harus mengelakkan nama yang serupa untuk pembolehubah apabila ia mempunyai makna yang sama sekali berbeza. Berikut ialah beberapa antonim yang sering ditemui digunakan dalam nama pembolehubah:- mula/akhir
- pertama terakhir
- dikunci/dikunci
- min/maks
- seterusnya/sebelumnya
- lama/baru
- dibuka/ditutup
- nampak/tak nampak
- sumber/sasaran
- sumber/destinasi
- atas bawah
Nama pembolehubah pendek
Apabila kita mempunyai pembolehubah seperti x atau n atau sesuatu seperti itu, kita tidak segera melihat niat orang yang menulis kod tersebut. Ia tidak jelas apa yang n buat. Memikirkan perkara itu memerlukan renungan yang lebih teliti (dan ini bermakna masa, masa, masa). Sebagai contoh, katakan kita mempunyai medan yang mewakili id pengguna yang bertanggungjawab. Daripada beberapa nama pembolehubah seperti x atau hanya id, kami akan menamakan pembolehubah ini "responsibleUserId", yang dengan serta-merta meningkatkan kebolehbacaan dan kandungan maklumat. Yang berkata, nama pendek seperti n mempunyai tempat sebagai pembolehubah tempatan dalam kaedah kecil, di mana blok kod yang melibatkan pembolehubah ini hanya beberapa baris panjang, dan nama kaedah menggambarkan dengan sempurna apa yang berlaku di sana. Melihat pembolehubah sedemikian, pembangun memahami bahawa ia adalah kepentingan kedua dan mempunyai skop yang sangat terhad. Akibatnya, skop mempunyai pergantungan tertentu pada panjang nama pembolehubah: semakin panjang nama, semakin global pembolehubah dan sebaliknya. Sebagai contoh, berikut ialah kaedah untuk mencari pengguna yang terakhir disimpan mengikut tarikh:
public User findLastUser() {
return findAllUsers().stream()
.sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
.findFirst()
.orElseThrow(() -> new ResourceNotFoundException("No user exists"));
}
Di sini kita menggunakan pembolehubah bernama pendek x dan y untuk mengisih strim, dan kemudian kita melupakannya.
Panjang optimum
Mari kita teruskan dengan topik panjang nama. Panjang nama optimum adalah antara n dan maximumNumberOfUsersInTheCurrentGroup. Dalam erti kata lain, nama pendek mengalami kekurangan makna, manakala nama yang terlalu panjang memanjangkan program tanpa menambah kebolehbacaan, dan kami terlalu malas untuk menulisnya setiap kali. Selain daripada kes yang diterangkan di atas untuk pembolehubah dengan nama pendek seperti n, anda harus berpegang pada panjang kira-kira 8-16 aksara. Ini bukan peraturan yang ketat, hanya garis panduan.Perbezaan kecil
Saya tidak boleh gagal untuk menyebut perbezaan halus dalam nama. Ini juga merupakan amalan buruk, kerana perbezaan ini boleh mengelirukan atau memerlukan banyak masa tambahan untuk melihatnya. Sebagai contoh, perbezaan antara InvalidDataAccessApiUsageException dan InvalidDataAccessResourceUsageException sukar untuk dikesan sepintas lalu. Kekeliruan juga sering timbul apabila menggunakan huruf kecil L dan O, kerana mereka boleh dengan mudah disalah anggap sebagai 1 dan 0. Dalam sesetengah fon perbezaannya lebih jelas, dalam sesetengahnya ia kurang.Erti yang
Kita perlu menjadikan nama bermakna, tetapi tidak mencipta kekaburan melalui sinonim, kerana, sebagai contoh, UserData dan UserInfo sebenarnya mempunyai makna yang sama. Dalam kes ini, kita perlu menggali lebih dalam ke dalam kod untuk memahami objek tertentu yang kita perlukan. Elakkan perkataan yang tidak menyampaikan maklumat yang berguna. Sebagai contoh, dalam firstNameString, mengapa kita memerlukan perkataan String? Bolehkah ini benar-benar objek Tarikh? Sudah tentu tidak. Jadi, kami hanya menggunakan firstName. Saya juga ingin menyebut pembolehubah boolean. Sebagai contoh, ambil boolean bernama flagDeleted. Perkataan bendera tidak mempunyai makna. Adalah lebih munasabah untuk memanggilnya sebagai Dipadam.Pemsalah maklumat
Saya juga ingin mengatakan beberapa perkataan tentang konvensyen penamaan yang salah. Katakan kita mempunyai pembolehubah bernama userActivityList, tetapi bukannya sebagai Senarai, objek ini ialah beberapa jenis bekas lain atau objek storan tersuai. Ini boleh mengelirukan pengaturcara biasa: lebih baik memanggilnya seperti userActivityGroup atau userActivities.Cari
Salah satu kelemahan nama pendek dan ringkas ialah ia sukar dicari dalam badan besar kod — Manakah yang lebih mudah dicari: "nama" atau "NAME_FOR_DEFAULT_USER"? Pilihan kedua, sudah tentu. Kita harus mengelakkan perkataan (huruf) yang sering ditemui dalam nama, kerana ia hanya akan meningkatkan bilangan fail yang sepadan semasa carian, yang tidak baik. Saya ingin mengingatkan anda bahawa pengaturcara menghabiskan lebih banyak masa membaca kod daripada menulisnya, jadi bijaklah menamakan elemen aplikasi anda. Tetapi bagaimana jika nama yang baik tidak dijumpai? Bagaimana jika nama kaedah tidak menerangkan fungsinya dengan baik? Di sinilah komen memasuki peringkat.Komen

Jenis komen
-
Komen undang-undang — Komen pada permulaan setiap fail sumber atas sebab undang-undang, contohnya:
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-
Komen bermaklumat — Komen yang mewakili penjelasan kod (menyediakan maklumat tambahan atau menghuraikan niat bahagian kod yang diberikan).
Sebagai contoh:
/* * 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 kes ini, anda boleh melakukannya tanpa komen, kerana nama kaedah dan parameternya, ditambah dengan fungsi yang sangat telus, menggambarkan diri mereka dengan baik.
-
Komen amaran — Komen bertujuan untuk memberi amaran kepada pembangun lain tentang akibat yang tidak diingini daripada tindakan (contohnya, memberi amaran kepada mereka tentang sebab ujian ditandakan sebagai @Abaikan):
// Takes too long to run // Don't run if you don't have a lot of time @Ignore @Test public void someIntegrationTest() { …… }
-
TODO — Komen yang merupakan nota tentang sesuatu yang perlu dilakukan pada masa hadapan yang tetapi atas sebab tertentu tidak boleh dilakukan sekarang. Ini adalah amalan yang baik, tetapi ulasan sedemikian harus dikaji secara berkala untuk menghapuskan yang tidak berkaitan dan mengelakkan kekacauan.
Contohnya ialah:
// 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 perhatikan hakikat bahawa kami perlu menambah perbandingan pengguna yang melakukan operasi muat turun (ID yang kami akan ekstrak daripada konteks keselamatan) dengan pengguna yang melakukan operasi simpan.
-
Mengukuhkan ulasan — Komen yang menekankan kepentingan keadaan yang pada pandangan pertama mungkin kelihatan tidak penting.
Sebagai contoh, pertimbangkan sekeping kaedah yang mengisi pangkalan data ujian 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
-
Komen Javadoc — Komen yang menerangkan API untuk fungsi tertentu. Mungkin terdapat ulasan yang paling berguna, kerana API yang didokumenkan adalah lebih mudah untuk digunakan. Yang berkata, mereka juga boleh ketinggalan zaman seperti mana-mana jenis ulasan lain. Jadi, jangan lupa bahawa sumbangan utama kepada dokumentasi dibuat bukan oleh komen, tetapi oleh kod yang baik.
Berikut ialah contoh kaedah yang agak biasa untuk mengemas kini 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);
Komen buruk
-
komen bergumam — Komen yang biasanya ditulis dengan tergesa-gesa dan maknanya hanya boleh difahami oleh pembangun yang menulisnya, kerana hanya dia yang melihat situasi bernuansa yang dirujuk oleh ulasan itu.
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 memuatkan tetapan ini? Adakah mereka sudah dimuatkan? Adakah kaedah ini sepatutnya menangkap pengecualian dan memuatkan tetapan lalai? Terlalu banyak soalan timbul yang hanya boleh dijawab dengan menyelidiki penyiasatan bahagian lain sistem.
- Komen berlebihan — Komen yang tidak membawa apa-apa beban semantik, kerana perkara yang berlaku dalam bahagian tertentu kod adalah jelas. Dalam erti kata lain, ulasan tidak lebih mudah dibaca daripada kod.
Mari lihat contoh:
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 komen sebegitu? Semua yang mereka jelaskan sudah jelas.
-
Komen yang tidak boleh dipercayai — Komen yang tidak benar dan hanya mengelirukan (maklumat salah). Sebagai contoh, inilah satu.
/** * 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 komen ini? Fakta bahawa ia terletak kepada kami sedikit, kerana sambungan ditutup jika isNotUsing adalah palsu, bukan sebaliknya, seperti yang dimaklumkan oleh ulasan itu.
-
Komen wajib — Komen yang dianggap wajib (cth ulasan Javadoc), tetapi sebenarnya kadangkala bertimbun secara berlebihan dan tidak boleh dipercayai serta tidak perlu (anda perlu memikirkan sama ada ulasan ini sebenarnya 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);
Adakah anda dapat memahami apa yang dilakukan oleh kaedah tanpa ulasan ini? Kemungkinan besar, ya, jadi komen menjadi sia-sia di sini.
Komen log — Komen yang kadangkala ditambahkan pada permulaan modul setiap kali ia 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 kemunculan sistem kawalan versi (contohnya, Git), ia menjadi kekacauan dan kerumitan kod yang tidak perlu.
Komen pengarang — Komen yang tujuannya adalah untuk menunjukkan orang yang menulis kod itu, supaya anda boleh menghubunginya dan membincangkan bagaimana, apa dan mengapa, cth:
* @author Bender Bending
Sekali lagi, sistem kawalan versi mengingati dengan tepat siapa yang menambah sedikit kod dan bila, jadi pendekatan ini tidak diperlukan.
Kod yang diulas — Kod yang diulas untuk satu sebab atau yang lain. Ini adalah salah satu tabiat yang paling teruk, kerana apa yang berlaku ialah anda mengulas sesuatu dan melupakannya, dan kemudian pembangun lain tidak mempunyai keberanian untuk memadamkannya (lagipun, bagaimana jika ia sesuatu yang berharga?).
// public void someMethod(SomeObject obj) {
// .....
// }
Akibatnya, kod yang dikomentari terkumpul seperti sampah. Anda tidak boleh meninggalkan kod sedemikian. Jika anda benar-benar memerlukannya, jangan lupa tentang sistem kawalan versi.
Komen tidak jelas — Komen yang menerangkan sesuatu dengan cara yang terlalu 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];
Komen harus menerangkan kod. Ia tidak sepatutnya memerlukan penjelasan. Jadi apa yang salah di sini? Apakah "bait penapis"? Apakah maksud "+ 1" itu? Kenapa betul-betul 300?
- Gunakan gaya yang mudah diselenggara: mengekalkan gaya yang terlalu mewah dan eksotik menjengkelkan dan memakan masa.
- Jangan gunakan ulasan hujung baris yang merujuk kepada satu baris: hasilnya ialah longgokan ulasan yang besar. Apatah lagi, sukar untuk memikirkan komen yang bermakna untuk setiap baris.
- Apabila anda mengarang ulasan, cuba jawab soalan "mengapa", bukan "bagaimana."
- Elakkan maklumat ringkas. Seperti yang saya katakan di atas, kita tidak memerlukan penjelasan untuk ulasan: komen itu sendiri adalah penjelasan.
- Anda boleh menggunakan ulasan untuk membuat nota unit dan julat nilai.
- Letakkan ulasan berdekatan dengan kod yang mereka huraikan.
GO TO FULL VERSION