2011-01-29 2 views
0

В некоторых кодовых файлах я видел комментарии, которые можно охарактеризовать как комментарии по умолчанию. Эти комментарии вы обычно найдете в каждом файле проекта, и, я считаю, в большинстве случаев они автоматически генерируются с помощью IDE. Мета-информация немного отличается. Это часть кода. Думаю, мне лучше показать это на примере. Это наш испытуемый (взяты из реальной жизни и упрощенный):Замечания по умолчанию и метаинформация в Java-классах/интерфейсах

public class UserServiceImpl implements IUserService { 

    //////////////////////////////////////////////////////////////////////// 
    // Constants 
    //////////////////////////////////////////////////////////////////////// 

    /** Logger for this class */ 
    @SuppressWarnings("unused") 
    private static final Log LOG = LogFactory.getLog(UserServiceImpl.class); 

    //////////////////////////////////////////////////////////////////////// 
    // Attributes 
    //////////////////////////////////////////////////////////////////////// 

    /** User DAO */ 
    private IUserDao userDao; 

    //////////////////////////////////////////////////////////////////////// 
    // Constructors 
    //////////////////////////////////////////////////////////////////////// 

    /** 
    * Default constructor 
    */ 
    public UserServiceImpl() { 
    } 

    public UserServiceImpl(final IUserDao userDao) { 
     this.userDao = userDao; 
    } 

    //////////////////////////////////////////////////////////////////////// 
    // Getter and Setter methods 
    //////////////////////////////////////////////////////////////////////// 

    /** 
    * @return value of {@link #userDao} field 
    * 
    */ 
    public IUserDao getUserDao() { 
     return userDao; 
    } 

    /** 
    * Sets {@link #userDao} field 
    * 
    * @param userDao User DAO 
    */ 
    public void setUserDao(final IUserDao userDao) { 
     this.userDao = userDao; 
    } 

    //////////////////////////////////////////////////////////////////////// 
    // Implemented/Overridden methods 
    //////////////////////////////////////////////////////////////////////// 

    /** 
    * 
    * @see IUserService#saveUser(User) 
    */ 
    @Override 
    public void saveUser(final User user) { 
     fillMissingFields(user); 
     userDao.saveUser(user); 
    } 

    /** 
    * 
    * @see IUserService#getUserById(Integer) 
    */ 
    @Override 
    public List<User> getUserById(final Integer id) { 
     return userDao.getUserById(id); 
    } 

    /** 
    * 
    * @see IUserService#getUserList(IEnvironmentContext) 
    */ 
    @Override 
    public List<User> getUserList(final @SuppressWarnings("unused") IEnvironmentContext context) { 
     return userDao.getUserList(); 
    } 

    //////////////////////////////////////////////////////////////////////// 
    // Helper methods 
    //////////////////////////////////////////////////////////////////////// 

    private void fillMissingFields(final User user) { 
     user.setLastUpdated(new Date()); 
    } 

    //////////////////////////////////////////////////////////////////////// 
    // toString() method 
    //////////////////////////////////////////////////////////////////////// 

    /** 
    * 
    * @see Object#toString() 
    */ 
    @Override 
    public String toString() { 
     return "UserServiceImpl {...}"; 
    } 
} 

Этот класс содержит много понятий, которые я хочу обсудить, так что я разделить их в этих типах:

1) Раздел по умолчанию комментарии - для каждого раздела класса есть один комментарий из трех строк (например, константы, конструкторы, ...). Обратите внимание, что я не говорю о логических разделах класса (например, // user managenet или // Account Balance calculation).

2) Комментарии по умолчанию Getter and Setter - комментарии для методов set/get, которые просто указывают, что соответствующие методы задают значение поля возврата.

3) Мета комментарии - комментарии, которые описывают смысл некоторых конструкций языка java. Примеры сверху: @see IUserService#saveUser(User) - указывает, что метод переопределен/реализован и расположение родительского метода, Default constructor - указывает, что он по умолчанию является конструктором класса Java, Logger for this class.

4) @SuppressWarnings («неиспользованные») - в моем конкретном примере он имел обыкновение говорить, что LOG не используется в классе (LOG не действительно никогда не используется в классе, но IDE не будет отображаться предупреждение) и context аргумент не используется, но все в порядке (при условии, что context - это общая информация, и обычно это нормально, если реализации не используют его).

5) I префикс для интерфейсов - префикс сообщает, что это интерфейс.

6) final для аргументов методы - предотвращает код в теле метода, чтобы изменить это значение

Я хотел бы знать Ваше мнение о комментариях по умолчанию и мета-информации в классах. Для того, чтобы сделать его более простым, я предлагаю вам проголосовать за каждый тип с оценками от +5 до -5:

+5 - Я думаю, что это обязательно, и это должно быть сделано каждым разработчик Java и должны даже применяться с инструментами (например, checkstyle)
...
- Мне все равно. Если кто-то скажет мне сделать это, я буду - эти комментарии не принесут никакого положительного или отрицательного значения.
...
-5 - Я категорически отвергаю всех, чтобы это сделать. Такие комментарии/метаданные по умолчанию должны быть удалены из класса, как только вы его увидите.

Я также твердо верю, что очень важно всегда объяснять вам вариант и отвечать на вопрос: почему вы так думаете? (Я лично стараюсь всегда следовать этому правилу). Поэтому я также призываю вас объяснить, какие моменты вы указали для определенного типа.

Я принимаю ответ с большинством голосов SO за одну неделю.

PS: Некоторые из вас могут подумать, что ответ очевиден, но поверьте мне, каждый из нас очень по-другому, и то, что самоочевидно для вас, может быть неожиданным для меня и наоборот. Поэтому я призываю вас участвовать в этом обсуждении в любом случае. (Буду признателен за это)

+0

Хотя, возможно, интересная тема для обсуждения, это не похоже на конкретный вопрос. –

ответ

3

Цель документации кода - помочь всем, кто читает код, понять это. Это и не более того. Это цель, на которую вы должны обратить внимание, и убедитесь, что вы ее никогда не потеряете. Стоимость документации может быть выражена как (<the time it would take me to read the code without the documentation> - <the time it takes me to read the code with the documentation>) * <my salary>) Вычитайте из нее время, необходимое для написания документации, умноженной на вашу зарплату, и вы получите чистую стоимость. Если это число, вероятно, будет отрицательным, не беспокойтесь о его написании. Эти формулы, очевидно, являются чисто теоретическими, но они позволяют нам задать несколько вопросов.

Являются ли комментарии в примере кода, помогли мне понять код? Ничего. Информация в них должна быть ослепительно очевидной для всех, кто имеет немного опыта работы на Java.

Они меня мешали? Да, поскольку мне потребовалось втрое больше, чтобы прокручивать его, чем это было бы без комментариев.

Если код должен был быть изменен, насколько сложно было бы сохранить комментарии согласованными? Я считаю, что это ключ. Более сложные разработки комментариев скорее всего будут нарушены, и это самое худшее, что может произойти: комментарий, который не просто лишний, но и вводит в заблуждение. Это похоже на кражу времени у разработчика.

В целом документация для документации неверна. Когда вы взвешиваете свой выбор документации, вы всегда должны иметь в виду читателя: как этот документ будет полезен им? Если вы это помните, вы сделаете правильный выбор.

+0

Спасибо! Хотелось бы, чтобы я мог проголосовать больше одного раза :) – tenshi

1

Я думаю, что не было бы страха от меня задавать этот вопрос и не рассказывал свое мнение об этом :). Вот мои голоса.

Чтобы сделать длинный рассказ коротким - я против невыполненных/автогенерированных комментариев. Я считаю, что комментарии не должны описывать само собой разумеющиеся вещи, объяснять конструкты/условные обозначения Java-кода или содержать информацию, которую можно легко извлечь с помощью IDE.

1) -5 (раздел по умолчанию комментарии)

Эти комментарии от одной стороны, пытаясь описать соглашения Java кода (или пытаются применять пользовательский макет класса они не следуют конвенции), а с другой стороны ломают их - например, давайте возьмем раздел // Helper methods: он обеспечивает размещение всех частных методов в этом разделе в конце файла. Это конфликтует с условными обозначениями Java (section 3.1.3):

Эти методы должны быть сгруппированы по функциональности, а не по объему или доступности. Например, метод частного класса может находиться между двумя методами общих экземпляров. Цель состоит в том, чтобы упростить чтение и понимание кода.

Очень легко поместить метод в неправильный раздел по ошибке - в этом случае они могут стать очень загадочными.

Худшее - это когда кто-то решает иметь это во всех классах независимо от того, что. Малые 10 линий длиной классы станут 50+ классов линии (смотрите пример в самом вопросе)

2) -5 Getter и Setter комментариев по умолчанию

Я считаю, это даже хуже, чем беспорядок. Я считаю, что они действительно утечки информации о внутренних классах. Весь смысл методов set/get заключается в том, чтобы скрыть факт, что они просто устанавливают и возвращают значение поля.

Эти комментарии само собой разумеются и не добавляют никакой полезной информации - только беспорядок в исходном коде.

Мы также должны учитывать, как работает наш мозг. Через некоторое время он научится игнорировать эти комментарии. В этом случае мы можем пропустить что-то важное или полезное.

3) -5 Мета комментарии

Комментарии, как // Logger for this class или // Default constructor самоочевидны и не приносит никакой полезной ценности.Если кому-то действительно нужны такие комментарии, чтобы лучше понять или прочитать код, я думаю, что пришло время ему прочитать какую-нибудь java-книгу или учебник для новичков.

@see IUserService#saveUser(User) не имеет для меня никакого смысла (учитывая все усилия по техническому обслуживанию, которые должны быть сделаны, чтобы сохранить эти комментарии в актуальном состоянии). Все основные Java IDE могут предоставить вам эту информацию - они дают видимые признаки того, что метод переопределяет/реализует что-то, что вы можете прыгать туда с помощью ярлыка, вы также можете увидеть, какой метод был переопределен в подсказке, если хотите.

Теперь рассмотрим возможность того, что этот метод в родительском классе (который вы переопределили) был удален (но в родительском классе вашего родительского класса все еще есть метод, который все еще имеет метод). В этом случае вы должны обновить эти комментарии во всех подклассах, чтобы синхронизировать их. И я могу сказать вам по опыту, что в какой-то момент большинство этих комментариев будет не синхронизировано и будет служить только двум целям: 1 - загрязнить код и 2 - загадку и ввести в заблуждение других разработчиков.

Теоретически вы можете найти способы синхронизировать их (написать плагин IDE, создать сложную переработку кода во время сборки и запустить ее каждую ночь и т. Д.), Но я твердо верю, что это просто пустая трата времени.

4) -3 @SuppressWarnings ("неиспользованные")

Я думаю, что @SuppressWarnings("unused") имеет это место в некоторых случаях, но не в примере, показанном в этом вопросе. LOG аннотирован, потому что он никогда не используется. Но если он никогда не используется, IMO LOG следует удалить из класса. Это личное статическое поле, поэтому он может использоваться только текущим классом. Если класс не использует его, это беспорядок.

Для context это также довольно бесполезно. context аргумент по определению не предполагается использовать. Он представляет информацию, которая может быть как-то полезна для подклассов, но не более того. Поэтому я думаю, что само собой разумеется, что context иногда не будет использоваться, и все в порядке. Я думаю, что IDEA часто может распознавать такие ситуации и не показывает предупреждения, если вы не используете context.

И для меня лично трудно прочитать подписи методов со всеми этими аннотациями @SuppressWarnings("unused") (особенно, если их несколько).

5) -4I Приставка для интерфейсов

Я лично считаю, что некрасиво и неестественно. Если мне нужен интерфейс для пользователя, я буду называть его User, а реализация будет иметь имя UserImpl. Я думаю, его можно сравнить с Uniform access principle. Пока это называется User Мне все равно, является ли он интерфейсом абстрактного класса или конкретного класса. Если автор интерфейса User в какой-то момент решает сделать его абстрактным классом - я не должен вносить изменения в свой код, потому что, скорее всего, он не изменит имя. Но это не относится к IUser.

С другой стороны, IDE дает нам более чем достаточно намеков, чтобы различать классы и интерфейсы.

Насколько я знаю, это название происходит от Microsoft COM. В C++ у них нет интерфейсов, поэтому они префикс конкретных классов C (например, CUser) и интерфейсные классы с I (например, IUser). В Java у нас есть интерфейсы и Naming Conventions.И я думаю, мы должны следовать за ними, если у нас нет повода для этого.

6) -1final для аргументов метода - предотвращает код в теле метода, чтобы изменить его значение

Пожалуйста, не понимают меня неправильно. Я считаю, что это действительно плохая практика для изменения значений аргументов. Я пытаюсь написать свой код как можно более неизменный код.

Но когда я читаю код, все эти final s в подписях метода просто беспорядочны для меня. Для меня само собой разумеется, что это должно быть окончательным. Но они делают подпись метода большой и трудночитаемой.

Я думаю, что должно быть возможно обеспечить соблюдение этого правила с помощью инструментов (таких как FindBugs или CheckStyle). И я думаю, что это лучший способ сделать это. Часто люди не пишут все эти final s сами, но позволяют IDE добавлять их, когда они сохраняют файл (например, eclipse может сделать). Но вы фактически изменили значение аргумента (случайно), тогда IDE просто не будет вставлять вам final.

Смежные вопросы