Penamaan yang betul
Nama yang betul meningkatkan kebolehbacaan kod, dengan itu menjimatkan masa untuk membiasakan diri, kerana lebih mudah untuk menggunakan kaedah apabila nama itu secara kasar menerangkan fungsinya. Memandangkan segala-galanya dalam kod terdiri daripada nama (pembolehubah, kaedah, kelas, objek fail, dll.), perkara ini menjadi sangat penting apabila mencipta kod yang betul dan bersih. Berdasarkan perkara di atas, nama itu harus menyampaikan maksud mengapa, sebagai contoh, pembolehubah wujud, apa yang dilakukan dan bagaimana ia digunakan. Saya akan perhatikan lagi dan lagi bahawa komen terbaik untuk menerangkan pembolehubah ialah nama yang betul.Penamaan Antara Muka
Antara muka biasanya menggunakan nama yang bermula dengan huruf besar dan ditulis dalam kotak unta (CamelCase). Ia pernah menjadi amalan yang baik apabila menulis antara muka untuk mengawalannya dengan I untuk menetapkannya sebagai antara muka (cth IUserService), tetapi ini agak hodoh dan mengganggu. Dalam kes sedemikian, adalah lebih baik untuk menulis tanpa ia (UserService), dan menambah -Impl (UserServiceImpl) pada pelaksanaannya. Nah, atau sebagai pilihan terakhir, tambahkan awalan C (CUserService) pada pelaksanaannya.Nama kelas
Sama seperti antara muka, nama menggunakan huruf besar dan menggunakan gaya unta (CamelCase). Tidak kira apa jenis kiamat yang berlaku, tidak kira berapa cepat tarikh akhir, tetapi jangan sekali-kali, ingat, nama kelas tidak boleh menjadi kata kerja! Nama kelas dan objek mestilah kata nama dan gabungannya (UserController, UserDetails, UserAccount dan sebagainya). Anda tidak seharusnya memberikan nama setiap kelas dengan singkatan aplikasi ini, kerana ini hanya akan menambah kerumitan yang tidak perlu (contohnya, kami mempunyai aplikasi Migrasi Data Pengguna, dan kami akan menambah UDM pada setiap kelas - UDMUserDeatils, UDMUserAccount, UDMUserController ).Nama kaedah
Biasanya nama kaedah bermula dengan huruf kecil, tetapi mereka juga menggunakan gaya unta (CamelCase). Di atas kita bercakap tentang fakta bahawa nama kelas tidak boleh menjadi kata kerja. Di sini keadaannya adalah bertentangan: nama kaedah mestilah kata kerja atau gabungannya dengan kata kerja: findUserById, findAllUsers, createUser dan sebagainya. Apabila mencipta kaedah (serta pembolehubah dan kelas), untuk mengelakkan kekeliruan, gunakan satu pendekatan penamaan. Contohnya, untuk mencari pengguna, kaedah boleh ditulis sebagai getUserById atau findUserById. Dan satu lagi: jangan gunakan jenaka dalam nama kaedah, kerana mereka mungkin tidak memahami jenaka, serta apa yang dilakukan oleh kaedah ini.Nama boleh ubah
Dalam kebanyakan kes, nama pembolehubah bermula dengan huruf kecil dan juga menggunakan huruf Camel, kecuali dalam kes di mana pembolehubah ialah pemalar global. Dalam kes sedemikian, semua huruf nama ditulis dalam huruf besar dan perkataan dipisahkan dengan garis bawah - “_”. Apabila menamakan pembolehubah, anda boleh menggunakan konteks yang bermakna untuk kemudahan. Dalam erti kata lain, apabila terdapat pembolehubah sebagai sebahagian daripada sesuatu yang lebih besar - contohnya, firstName, lastName, status - dalam kes sedemikian, anda boleh menambah awalan yang menunjukkan objek yang pembolehubah ini adalah sebahagiannya. Contohnya: userFirstName, userLastName, userStatus. Anda juga perlu mengelakkan nama yang serupa untuk pembolehubah apabila ia mempunyai makna yang sama sekali berbeza. Antonim biasa untuk 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. Tidak jelas apa kaedah n lakukan: ia memerlukan pemikiran yang lebih bernas (dan itulah masa, masa, masa). Sebagai contoh, kami mempunyai medan - id pengguna yang bertanggungjawab, dan bukannya beberapa nama seperti x atau hanya id, kami akan memanggil pembolehubah ini responsibleUserId, yang dengan serta-merta meningkatkan kebolehbacaan dan kebermaknaan. Walau bagaimanapun, nama pendek seperti n mempunyai tempatnya sebagai perubahan setempat kepada kaedah kecil, di mana blok kod dengan perubahan itu hanyalah beberapa baris kod, dan nama kaedah menerangkan dengan sempurna apa yang berlaku di sana. Seorang pembangun, melihat pembolehubah sedemikian, memahami kepentingan kedua dan skopnya yang sangat terhad. Akibatnya, terdapat sedikit pergantungan pada panjang nama pembolehubah: semakin lama, semakin global pembolehubah itu dan sebaliknya. Sebagai contoh, kaedah untuk mencari pengguna terakhir yang disimpan mengikut tarikh:public User findLastUser() {
return findAllUsers().stream()
.sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
.findFirst()
.orElseThrow(() -> new ResourceNotFoundException("Any user doesn't exist "));
}
Di sini kami menggunakan nama pendek x dan y untuk menetapkan pengisihan aliran, dan melupakannya.
Panjang optimum
Mari kita sambung topik panjang nama. Panjang nama optimum berada di antara panjang nama maximumNumberOfUsersInTheCurrentGroup dan n. Iaitu, yang terlalu pendek mengalami kekurangan makna, dan yang terlalu panjang meregangkan program tanpa menambah kebolehbacaan, dan mereka terlalu malas untuk menulisnya setiap kali. Tidak mengambil kira kes di atas, untuk pembolehubah dengan nama pendek seperti n, anda perlu mengekalkan panjangnya kepada kira-kira 8-16 aksara. Ini bukan peraturan yang ketat: lebih kepada garis panduan.Perbezaan kecil
Saya tidak boleh mengabaikan perbezaan kecil dalam nama, kerana ini juga merupakan amalan buruk, kerana anda boleh keliru atau menghabiskan banyak masa tambahan untuk melihat perbezaan kecil dalam nama. Sebagai contoh, perbezaan antara InvalidDataAccessApiUsageException dan InvalidDataAccessResourceUsageException sukar untuk dikesan sepintas lalu. Selain itu, maklumat salah selalunya boleh timbul apabila menggunakan L dan O kecil, kerana ia boleh dikelirukan dengan mudah dengan 1 dan 0: dalam sesetengah fon perbezaannya lebih jelas, dalam yang lain kurang begitu.Bahagian semantik
Kita perlu meletakkan bahagian semantik ke dalam nama, tetapi tidak terlalu banyak menggunakan sinonim, kerana, sebagai contoh, UserData dan UserInfo sebenarnya mempunyai makna yang sama, dan kita perlu menggali sedikit lebih mendalam ke dalam kod untuk memahami objek khusus yang kita perlukan. . Elakkan perkataan yang tidak bermaklumat, contohnya, firstNameString: mengapa kita memerlukan rentetan perkataan? Bolehkah nama menjadi objek jenis tarikh? Sudah tentu tidak: oleh itu, hanya - firstName. Sebagai contoh, saya ingin menyebut pembolehubah boolean, sebagai contoh, flagDelete. Perkataan bendera tidak membawa sebarang makna semantik. Adalah lebih munasabah untuk memanggilnya - isDelete.Maklumat salah
Saya juga ingin mengatakan beberapa perkataan tentang penamaan yang salah. Katakan kita mempunyai nama userActivityList, dan objek yang dinamakan demikian bukanlah daripada jenis Senarai, tetapi beberapa bekas lain atau objek tersuai untuk penyimpanan. Ini boleh mengelirukan pengaturcara biasa: adalah lebih baik untuk memanggilnya sesuatu seperti userActivityGroup atau userActivities.Cari
Salah satu kelemahan nama pendek dan ringkas ialah ia sukar dicari dalam jumlah kod yang banyak, kerana apakah yang lebih mudah dicari: pembolehubah dipanggil nama atau NAME_FOR_DEFAULT_USER? Sudah tentu, pilihan kedua. Ia adalah perlu untuk mengelakkan perkataan (huruf) yang kerap muncul dalam nama, kerana ini hanya akan meningkatkan bilangan fail yang ditemui semasa carian, yang tidak baik. Kami ingin mengingatkan anda bahawa pengaturcara menghabiskan lebih banyak masa membaca kod daripada menulisnya, jadi berhati-hati dengan penamaan elemen aplikasi anda. Tetapi bagaimana jika anda tidak berjaya menamakannya? Bagaimana jika nama kaedah tidak menerangkan fungsinya dengan baik? Di sinilah ia memainkan peranan, item kami seterusnya ialah komen.Komen
Tiada apa-apa seperti ulasan yang berkaitan, tetapi tiada apa-apa yang mengacaukan modul seperti komen yang tidak bermakna, lapuk atau mengelirukan. Ia adalah pedang bermata dua, bukan? Namun, anda tidak seharusnya menganggap komen sebagai kebaikan yang tidak jelas: sebaliknya, sebagai kejahatan yang lebih kecil. Lagipun, komen, pada dasarnya, adalah pampasan untuk pemikiran yang tidak berjaya dinyatakan dalam kod. Sebagai contoh, kami menggunakannya untuk menyampaikan intipati kaedah jika ternyata terlalu mengelirukan. Dalam keadaan sedemikian, adalah lebih baik untuk memfaktorkan semula kod dengan betul daripada menulis nota deskriptif. Semakin lama komen, semakin teruk, kerana kod itu cenderung berkembang dan berkembang, tetapi ulasan itu mungkin kekal sama, dan semakin jauh ia pergi, semakin meragukan nota ini. Komen yang tidak tepat adalah lebih teruk daripada tiada ulasan, kerana ia mengelirukan dan menipu, memberikan jangkaan palsu. Dan walaupun kita mempunyai kod yang sangat rumit, ia masih berbaloi untuk tidak mengulas mengenainya, tetapi menulisnya semula.Jenis komen
-
ulasan undang-undang ialah ulasan yang ditinggalkan pada permulaan setiap fail kod sumber atas sebab undang-undang, seperti:
* 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 memberikan penjelasan tentang kod (menyediakan maklumat tambahan atau niat bahagian kod yang diberikan.
Sebagai contoh:
/* * Объединяет пользователя из бд и пришедшего для обновления * Когда в requestUser поле пустое, оно заполняется старыми данными из 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 hujahnya, ditambah dengan fungsi yang sangat telus, menggambarkan diri mereka dengan baik.
-
komen amaran - ulasan yang tujuannya adalah untuk memberi amaran kepada pembangun lain tentang akibat yang tidak diingini daripada beberapa tindakan (contohnya, mengapa ujian ditandakan sebagai @Abaikan):
// Слишком долго отрабатывает // Не запускайте, если не располагаете избытком времени @Ignore @Test public void someIntegrationTest() { …… }
-
TODO - komen yang merupakan nota untuk masa depan yang perlu dilakukan, tetapi atas sebab tertentu tidak boleh dilakukan sekarang. Ini adalah amalan yang baik, tetapi ia masih perlu disemak secara berkala untuk membuang yang tidak berkaitan untuk mengelakkan kekacauan.
Примером послужит:
//TODO: Add a check for the current user ID (when will be created security context) @Override public Resource downloadFile(File file) { return fileManager.download(file); }
Тут мы помечаем, что нужно добавить проверку юзера, который скачивает (id которого мы вытащим из security контекста) с тем, кто сохранил.
-
усorвающий комментарий — комментарий, подчеркивающий важность Howого-то обстоятельства, что на первый взгляд может показаться несущественным.
Как пример, кусочек метода, заполняющий тестовую БД, некими скриптами:
Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8) .trim() .split(";")) .forEach(jdbcTemplate::update); // Вызов trim() очень важен, убирает возможные пробелы в конце скрипта // чтобы при считке и разбивке на отдельные requestы не было пустых
-
javaDoc — комментарии, которые описывают API определенного функционала для общего пользования. Наверное, самые полезные комментарии, так How с documentированным API в разы легче работать, но они также могут устаревать, How и любые другие. Поэтому не забываем, что главный вклад в documentацию вносится не комментариями, а хорошим codeом.
Пример вполне обычного метода обновления пользователя:
/** * Обновляет передаваемые поля для пользователя по id. * * @param id id обновляемого пользователя * @param user пользователь с заполненными полями для обновления * @return обновленный пользователь */ User update(Long id, User user);
Плохие сценарии комментариев
-
бормочущий комментарий — комментарии, которые обычно пишут на скорую руку, смысл которых понятен только разработчику, писавшего их, так How только он видит ту ситуацию с теми нюансами, на которые он и ссылается.
Рассмотрим данный пример:
public void configureSomeSystem() { try{ String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE); FileInputStream stream = new FileInputStream(configPath); } catch (FileNotFoundException e) { //В случае отсутствия конфигурационного file, загружается конфигурация по умолчанию } }
Кто загружает эти настройки? Были ли они загружены ранее? Метод предназначен для перехвата исключений и вызова дефолтных настроек? Слишком много вопросов возникает, ответы на которые можно получить лишь углубившись в изучение других частей системы.
-
избыточный комментарий — комментарий, который не несёт смысловой нагрузки, так How и так понятно что происходит в заданном участке codeа (он читается не проще, чем code).
Смотрим пример:
public class JdbcConnection{ public class JdbcConnection{ /** * Журнальный компонент, связанный с текущим классом */ private Logger log = Logger.getLogger(JdbcConnection.class.getName()); /** * Создаёт и возвращает connection с помощью входящих параметров */ 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; }
Какой смысл таких комментариев, если мы и так всё прекрасно видим
-
недостоверные комментарии — комментарии, не соответствующие истине и лишь вгоняющие в заблуждение (дезинформирующие). Как например:
/** * Вспомогательный метод, закрывает соединение со сканером, если isNotUsing истинно */ private void scanClose(Scanner scan, boolean isNotUsing) throws Exception { if (!isNotUsing) { throw new Exception("The scanner is still in use"); } scan.close(); }
What в этом комменте не так? А то, что он немножко врёт нам, ведь соединение закрывается, если isNotUsing = false, но ниHow не наоборот, How нам вещает пометка.
-
обязательные комментарии — комментарии, которые считают обязательными (Javadoc), но кои по факту иногда бывают излишне нагромождающими, недостоверными и ненужными (нужно задуматься, а нужны ли здесь такие комментарии).
Пример:
/** * Creation пользователя по переданным параметрам * @param firstName Name созданного пользователя * @param middleName среднее Name созданного пользователя * @param lastName фамorя созданного пользователя * @param age возраст созданного пользователя * @param address addressс созданного пользователя * @return пользователь который был создан */ User createNewUser(String firstName, String middleName, String lastName, String age, String address);
Смогли бы вы понять, что делает метод без этих комментариев? Скорее всего да, поэтому комментарии в этом случае стают бессмысленными.
-
журнальные комментарии — комментарии, которые иногда добавляют в начало модуля, при каждом его редактировании (что-то вроде журнала вносимых изменений).
/** * Записи ведутся с 09 января 2020; ********************************************************************** * 09.01.2020 : Обеспечение соединения с БД с помощью Jdbc Connection; * 15.01.2020 : Добавление интерфейсов уровня дао для работы с БД; * 23.01.2020 : Добавление интеграционных тестов для БД; * 28.01.2020 : Имплементация интерфейсов уровня дао; * 01.02.2020 : Разработка интерфейсов для сервисов, * согласно требованиям прописанным в user stories; * 16.02.2020 : Имплементация интерфейсов сервисов * (реализация бизнес логики связанной с работой БД); * 25.02.2020 : Добавление тестов для сервисов; * 08.03.2020 : Празднование восьмого марта(Миша опять в хлам); * 21.03.2020 : Рефакторинг сервис слоя; */
Когда-то этот проход был оправдан, но с появлением систем управления исходным codeом (например — Git), это стало лишним нагромождением и усложнением codeа.
-
комментарии ссылки на авторов — комментарии, преднаmeaningм которых является, указание человека, писавшего code, чтобы можно было связаться и обсудить, How что и зачем:
* @author Bender Benderovich
Опять же, системы контроля версий прекрасно запоминают, кто и когда добавил данный code, и подобный подход излишен.
-
kod komen ialah kod yang telah diulas untuk satu sebab atau yang lain. Salah satu tabiat yang paling teruk, kerana anda mengulasnya dan terlupa, dan pembangun lain tidak mempunyai keberanian untuk memadamkannya (bagaimana jika ia sesuatu yang berharga).
// public void someMethod(SomeObject obj) { // ..... // }
Akibatnya, ia terkumpul seperti sampah. Dalam apa jua keadaan, kod sedemikian tidak boleh ditinggalkan. Jika anda benar-benar memerlukannya, jangan lupa tentang sistem kawalan versi.
-
komen yang tidak jelas ialah ulasan yang menggambarkan sesuatu dengan cara yang tidak perlu rumit.
/* * Начать с массива, размер которого достаточен для хранения * всех byteов данных (плюс byteы фильтра) с запасом, плюс 300 byte * для данных заголовка */ this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
Komen harus menerangkan kod, tidak memerlukan penjelasan itu sendiri. Apa yang berlaku di sini? Apakah "bait penapis"? Apakah kaitan +1 dengan ini? Kenapa betul-betul 300?
- Gunakan gaya yang mudah diselenggara: mengekalkan gaya yang terlalu mewah dan eksotik boleh menjengkelkan dan memakan masa.
- Jangan gunakan ulasan pada penghujung baris yang merujuk kepada satu baris: ini menghasilkan longgokan ulasan yang besar, dan sukar untuk menghasilkan ulasan ekspresif untuk setiap baris.
- Semasa membuat ulasan, cuba jawab soalan "mengapa" dan bukannya "bagaimana".
- Elakkan singkatan. Seperti yang saya katakan di atas, kita tidak memerlukan penjelasan untuk ulasan: komen adalah penjelasan.
- Anda boleh menggunakan ulasan untuk menandakan unit ukuran dan julat nilai yang boleh diterima.
- Letakkan ulasan berdekatan dengan kod yang mereka huraikan.
GO TO FULL VERSION