JavaRush /Java Blog /Random-KO /코드 규칙: 적절한 이름 지정, 좋은 댓글과 나쁜 댓글의 힘

코드 규칙: 적절한 이름 지정, 좋은 댓글과 나쁜 댓글의 힘

Random-KO 그룹에 게시되었습니다
코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 1 다른 사람의 코드를 이해해야 했던 적이 얼마나 자주 있었습니까? 몇 시간이 아니라 무슨 일이 일어나고 있는지 논리를 이해하기 위해 며칠을 보낼 때. 재미있는 점은 이 코드를 작성한 사람에게는 모든 것이 명확하고 매우 투명하다는 것입니다. 그리고 이것은 놀라운 일이 아닙니다. 결국 완벽하거나 이상적인 코드는 매우 모호한 개념입니다. 각 개발자는 각각 세계와 코드에 대한 자신의 비전을 가지고 있기 때문입니다. 나는 동료와 동일한 코드를 보았지만 코드의 정확성과 청결성에 대해 서로 다른 의견을 가진 상황을 여러 번 경험했습니다. 코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 2익숙한 느낌이죠? 그러나 오랜 시간에 걸쳐 준수해야 할 몇 가지 사항이 있으며 이는 궁극적으로 우리에게 유리하게 작용할 것입니다. 왜냐하면 귀하가 코드를 받고 싶은 상태로 코드를 남겨두면 세상이 조금 더 행복해지고 더 행복해질 것이기 때문입니다. 청소기. 코드 작성 규칙(또는 작은 가이드)에 대한 지난 기사코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 3 에서 우리는 시스템 전체와 객체, 인터페이스, 클래스, 메소드 및 변수와 같은 요소를 작성하기 위한 권장 사항에 대해 조금 다루었습니다. 여기서 나는 특정 요소의 올바른 이름을 간략하게 언급했습니다. 오늘 저는 이에 대해 정확하게 이야기하고 싶습니다. 올바른 이름을 사용하면 코드를 훨씬 쉽게 읽을 수 있기 때문입니다. 우리는 반사와 코드의 작은 주석 예를 통해 올바른 코드에 대한 주제를 마무리하겠습니다. 이것이 좋은지 나쁜지입니다. 그럼 시작해 보겠습니다.

올바른 이름 지정

올바른 이름은 코드의 가독성을 향상시켜, 이름이 해당 기능을 대략적으로 설명하는 경우 메소드를 사용하는 것이 훨씬 쉽기 때문에 익숙해지는 데 드는 시간을 절약합니다. 코드의 모든 것은 이름(변수, 메소드, 클래스, 파일 객체 등)으로 구성되므로 정확하고 깔끔한 코드를 작성할 때 이 점이 매우 중요합니다. 위의 내용을 바탕으로 이름은 변수가 존재하는 이유, 기능 및 사용 방법 등의 의미를 전달해야 합니다. 변수를 설명하는 가장 좋은 설명은 변수의 정확한 이름이라는 점을 계속해서 언급하겠습니다. 코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 4

명명 인터페이스

인터페이스는 일반적으로 대문자로 시작하고 카멜 케이스(CamelCase)로 작성된 이름을 사용합니다. 예전에는 인터페이스(예: IUserService)를 지정하기 위해 인터페이스 앞에 I를 붙이는 것이 좋은 습관이었지만 이는 매우 보기 흉하고 산만합니다. 그러한 경우에는 UserService 없이 작성하고 구현에 -Impl(UserServiceImpl)을 추가하는 것이 좋습니다. 글쎄, 또는 최후의 수단으로 구현에 접두사 C(CUserService)를 추가합니다.

클래스 이름

인터페이스와 마찬가지로 이름은 대문자로 시작하고 카멜 스타일(CamelCase)을 사용합니다. 어떤 종말이 일어나더라도, 마감일이 아무리 빨라도, 클래스 이름은 절대로 동사가 되어서는 안 된다는 점, 기억하세요! 클래스 및 객체 이름은 명사와 그 조합(UserController, UserDetails, UserAccount 등)이어야 합니다. 이 애플리케이션의 약어로 각 클래스의 이름을 제공하면 안 됩니다. 이렇게 하면 불필요한 복잡성만 추가될 뿐입니다(예를 들어 사용자 데이터 마이그레이션 애플리케이션이 있고 각 클래스에 UDM을 추가합니다(UDMUserDeatils, UDMUserAccount, UDMUserController). ).

메소드 이름

일반적으로 메소드 이름은 소문자로 시작하지만 카멜 스타일(CamelCase)을 사용하기도 합니다. 위에서 우리는 클래스 이름이 동사가 되어서는 안 된다는 사실에 대해 이야기했습니다. 여기서 상황은 정반대입니다. 메소드의 이름은 동사이거나 동사와의 조합이어야 합니다(findUserById, findAllUsers, createUser 등). 메소드(변수 및 클래스 포함)를 생성할 때 혼동을 피하기 위해 하나의 명명 방식을 사용하십시오. 예를 들어, 사용자를 찾으려면 메소드를 getUserById 또는 findUserById로 작성할 수 있습니다. 그리고 한 가지 더: 메소드 이름에 유머를 사용하지 마십시오. 왜냐하면 메소드가 농담과 이 메소드의 역할을 이해하지 못할 수 있기 때문입니다.

변수 이름

대부분의 경우 변수 이름은 소문자로 시작하고 변수가 전역 상수인 경우를 제외하고는 Camelcase도 사용합니다. 이 경우 이름의 모든 문자는 대문자로 작성되고 단어는 밑줄("_")로 구분됩니다. 변수 이름을 지정할 때 편의를 위해 의미 있는 컨텍스트를 사용할 수 있습니다. 즉, 변수가 더 큰 것(예: firstName, lastName, status)의 일부인 경우 이 변수가 포함된 개체를 나타내는 접두사를 추가할 수 있습니다. 예: userFirstName, userLastName, userStatus. 또한 완전히 다른 의미를 갖는 변수에 대해 비슷한 이름을 사용하는 것을 피해야 합니다. 변수에 대한 일반적인 반의어:
  • 시작/끝
  • 처음/마지막
  • 잠김/잠금 해제
  • 최소 최대
  • 다음/이전
  • 오래된/새로운
  • 열었다/닫았다
  • 보이는/보이지 않는
  • 소스/타겟
  • 소스/대상
  • 위아래

짧은 변수 이름

x나 n 같은 변수가 있으면 코드를 작성한 사람의 의도를 즉시 알 수 없습니다. n이 어떤 방법을 하는지는 확실하지 않습니다. 더 사려 깊은 사고가 필요합니다(그리고 그것은 시간, 시간, 시간입니다). 예를 들어, 책임 사용자의 ID라는 필드가 있고 x와 같은 이름이나 ID 대신 이 변수를 ResponsibilityUserId라고 부르면 가독성과 의미가 즉시 향상됩니다. 그러나 n과 같은 짧은 이름은 작은 메서드에 대한 로컬 변경으로 자리잡습니다. 여기서 해당 변경이 포함된 코드 블록은 단지 몇 줄의 코드일 뿐이며 메서드 이름은 거기서 일어나는 일을 완벽하게 설명합니다. 이러한 변수를 보는 개발자는 이차적인 중요성과 매우 제한된 범위를 이해합니다. 결과적으로 변수 이름의 길이에 어느 정도 의존성이 있습니다. 길이가 길수록 변수는 더 전역적이며 그 반대도 마찬가지입니다. 예를 들어, 마지막으로 저장된 사용자를 날짜별로 찾는 방법은 다음과 같습니다.
public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("Any user doesn't exist "));
}
여기서는 짧은 이름 x와 y를 사용하여 스트림 정렬을 설정하고 잊어버립니다.

최적의 길이

이름 길이에 대한 주제를 계속합시다. 최적의 이름 길이는 maximumNumberOfUsersInTheCurrentGroup 이름 길이와 n 사이입니다. 즉, 너무 짧은 것은 의미 부족으로 고통 받고, 너무 긴 것은 가독성을 추가하지 않고 프로그램을 늘리며 매번 작성하기에는 너무 게으른 것입니다. 위의 경우를 고려하지 않고 n과 같은 짧은 이름을 가진 변수의 경우 길이를 약 8~16자로 유지해야 합니다. 이는 엄격한 규칙은 아니며 지침에 가깝습니다.

작은 차이

이름의 미묘한 차이를 무시할 수는 없습니다. 이는 또한 나쁜 습관이기 때문입니다. 이름의 사소한 차이를 알아차리면 혼란스러워지거나 많은 추가 시간을 소비할 수 있기 때문입니다. 예를 들어 InvalidDataAccessApiUsageException과 InvalidDataAccessResourceUsageException의 차이점은 한눈에 파악하기 어렵습니다. 또한 작은 L과 O를 사용할 때 종종 잘못된 정보가 발생할 수 있습니다. 왜냐하면 1과 0과 쉽게 혼동될 수 있기 때문입니다. 일부 글꼴에서는 차이가 더 뚜렷하고 다른 글꼴에서는 덜 그렇습니다.

의미 부분

이름에 의미 부분을 넣어야 하지만 동의어를 너무 많이 사용하면 안 됩니다. 예를 들어 UserData와 UserInfo는 실제로 동일한 의미를 갖고 있기 때문에 필요한 특정 개체가 무엇인지 이해하려면 코드를 좀 더 깊이 파헤쳐야 합니다. . 예를 들어 firstNameString과 같이 정보가 없는 단어는 피하세요. string이라는 단어가 왜 필요한가요? 이름이 날짜 유형 객체일 수 있나요? 물론 그렇지 않습니다. 따라서 간단하게 - firstName입니다. 예를 들어 flagDelete와 같은 부울 변수를 언급하고 싶습니다. 플래그라는 단어에는 의미상 의미가 없습니다. isDelete라고 부르는 것이 더 합리적이었을 것입니다.

그릇된 정보

또한 잘못된 명명에 대해 몇 마디 말씀드리고 싶습니다. userActivityList라는 이름이 있고 그렇게 명명된 개체가 목록 유형이 아니라 저장을 위한 다른 컨테이너 또는 사용자 정의 개체라고 가정해 보겠습니다. 이는 일반 프로그래머에게 혼란을 줄 수 있습니다. userActivityGroup 또는 userActivities와 같은 이름으로 부르는 것이 더 좋습니다.

찾다

짧고 간단한 이름의 단점 중 하나는 많은 양의 코드에서 찾기가 어렵다는 것입니다. 이름 또는 NAME_FOR_DEFAULT_USER라는 변수를 찾는 것이 더 쉬울 것이기 때문입니다. 물론 두 번째 옵션입니다. 이름에 자주 등장하는 단어(문자)를 피하는 것이 필요합니다. 그렇게 하면 검색 중에 발견되는 파일의 수가 늘어나게 되므로 좋지 않습니다. 프로그래머는 코드를 작성하는 것보다 코드를 읽는 데 더 많은 시간을 소비하므로 애플리케이션 요소의 이름 지정에 유의하세요. 하지만 이름을 성공적으로 지정하지 못했다면 어떻게 될까요? 메소드 이름이 해당 기능을 잘 설명하지 못하는 경우 어떻게 해야 합니까? 이것이 바로 중요한 부분입니다. 다음 항목은 주석입니다.

코멘트

코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 5관련된 댓글만큼 좋은 것은 없지만 의미가 없거나 오래되었거나 오해의 소지가 있는 댓글처럼 모듈을 어수선하게 만드는 것도 없습니다. 양날의 검이죠? 하지만 댓글을 명백한 선으로 취급해서는 안 됩니다. 오히려 덜 악한 것으로 취급해야 합니다. 결국, 주석은 본질적으로 코드에서 성공적으로 표현되지 못한 생각에 대한 보상입니다. 예를 들어, 메소드가 너무 혼란스러울 경우 메소드의 본질을 전달하기 위해 메소드를 사용합니다. 이러한 상황에서는 설명적인 메모를 작성하는 것보다 코드를 올바르게 리팩토링하는 것이 좋습니다. 주석이 오래될수록 코드는 성장하고 발전하는 경향이 있기 때문에 더 나쁩니다. 그러나 주석은 동일하게 유지될 수 있고, 더 나아갈수록 이러한 메모는 더욱 모호해집니다. 부정확한 댓글은 댓글이 없는 것보다 훨씬 더 나쁩니다. 왜냐하면 잘못된 기대를 갖게 하고 혼란을 주고 속이기 때문입니다. 그리고 매우 까다로운 코드가 있더라도 이에 대해 주석을 달지 않고 다시 작성하는 것이 좋습니다.

댓글 유형

  • 법적 의견은 다음과 같은 법적 이유로 각 소스 코드 파일의 시작 부분에 남겨진 의견입니다.

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

  • 정보 주석은 코드에 대한 설명을 제공하는 주석입니다(추가 정보 또는 특정 코드의 의도 제공).

    예로서:

    /*
    * Объединяет пользователя из бд и пришедшего для обновления
    * Когда в 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()
           );
           }

    이 경우, 메소드의 이름과 인수가 매우 투명한 기능과 결합되어 그 자체를 아주 잘 설명하므로 주석 없이 수행할 수 있습니다.

  • 경고 주석 - 일부 작업의 바람직하지 않은 결과에 대해 다른 개발자에게 경고하는 것이 목적인 주석(예: 테스트가 @Ignore로 표시된 이유):

    // Слишком долго отрабатывает
    // Не запускайте, если не располагаете избытком времени
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
  • TODO - 앞으로 수행해야 할 메모이지만 어떤 이유로 지금은 수행할 수 없는 주석입니다. 이는 좋은 방법이지만, 혼란을 피하기 위해 관련 없는 항목을 제거하려면 정기적으로 검토해야 합니다.

    Примером послужит:

    //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);

Плохие сценарии комментариев

코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 7
  • бормочущий комментарий — комментарии, которые обычно пишут на скорую руку, смысл которых понятен только разработчику, писавшего их, так 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, и подобный подход излишен.

  • 주석 처리된 코드는 이런저런 이유로 주석 처리된 코드입니다. 최악의 습관 중 하나는 당신이 그것을 주석으로 처리하고 잊어버렸고, 다른 개발자들은 그것을 삭제할 용기가 없기 때문입니다(귀중한 것이라면 어떨까요).

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

    결과적으로 쓰레기처럼 쌓이게 됩니다. 어떠한 경우에도 그러한 코드를 남겨서는 안됩니다. 정말로 필요하다면 버전 관리 시스템을 잊지 마세요.

  • 명확하지 않은 댓글은 불필요하게 복잡한 방식으로 무언가를 설명하는 댓글입니다.

    /*
        * Начать с массива, размер которого достаточен для хранения
        * всех byteов данных (плюс byteы фильтра) с запасом, плюс 300 byte
        * для данных заголовка
        */
    this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];

    주석은 코드를 설명해야 하며 설명 자체는 필요하지 않습니다. 여기에 뭐가 있지? "필터 바이트"란 무엇입니까? +1이 그것과 무슨 관련이 있나요? 왜 정확히 300인가요?

댓글을 작성하기로 결정한 경우 댓글 사용에 대한 몇 가지 팁은 다음과 같습니다.
  1. 유지 관리가 쉬운 스타일을 사용하세요. 너무 화려하고 이국적인 스타일을 유지하는 것은 귀찮고 시간이 많이 걸릴 수 있습니다.
  2. 한 줄을 참조하는 줄 끝에 주석을 사용하지 마십시오. 이렇게 하면 주석이 너무 많아지고 각 줄에 대해 표현 가능한 주석을 작성하기가 어렵습니다.
  3. 댓글을 작성할 때 '어떻게'보다는 '왜'라는 질문에 답하도록 노력하세요.
  4. 약어를 사용하지 마세요. 위에서 말했듯이 댓글에 대한 설명은 필요하지 않습니다. 댓글은 설명입니다.
  5. 주석을 사용하여 측정 단위와 허용 가능한 값의 범위를 표시할 수 있습니다.
  6. 주석이 설명하는 코드 가까이에 주석을 배치하세요.
결과적으로 저는 여전히 여러분께 상기시켜 드리고 싶습니다. 가장 좋은 댓글은 댓글이 없고 그 대신 애플리케이션에 적절한 이름을 지정하는 것입니다. 일반적으로 대부분의 경우 우리는 이미 기성 코드를 사용하여 작업하고 이를 유지 관리하고 확장합니다. 이 코드가 읽고 이해하기 쉬우면 훨씬 더 편리합니다. 잘못된 코드가 방해가 되고 바퀴에 말을 걸고 신속함이 충실한 동반자이기 때문입니다. 그리고 나쁜 코드가 많을수록 성능이 떨어지기 때문에 때때로 리팩터링이 필요합니다. 그러나 처음부터 후속 개발자가 당신을 찾아 죽이기를 원하지 않는 코드를 작성하려고 한다면 리팩터링 빈도를 줄여야 합니다. 그러나 제품에 대한 조건과 요구 사항은 지속적으로 변경되고 추가 연결을 추가하여 보완되며 이로부터 벗어날 수 없기 때문에 여전히 필요합니다. 마지막으로 여기 , 여기여기에서 이 주제에 대해 알아볼 수 있는 몇 가지 흥미로운 링크를 남겨 두겠습니다 . 읽어주신 모든 분들께 감사드립니다.) )코드 작성 규칙: 올바른 이름 지정의 힘, 좋은 댓글과 나쁜 댓글 - 8
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION