Соглашения о присвоении имен метода Java: Слишком много методов считывания

Почему имена методов Java используют "получить" префикс так экстенсивно? По крайней мере, в моих программах Java существует много методов с именами, запускающимися со слова, "добираются". Процент получать-методов подозрительно высок. Я начинаю чувствовать, что слово "добирается", теряет его значение из-за инфляции. Это - шум в моем коде.

Я заметил, что существует другое соглашение о присвоении имен, используемое в функциональном / декларативном программировании и МН / SQL. Имя метода просто указывает, что возвращает метод. Вместо account.getAmount() или Time.getIsoFormattedDateString(Date date) они будут использовать account.amount() и Time.isoFormattedDateString(Date date). Это имеет смысл мне, поскольку название функции описывает результат оценки метода (предполагающий, что нет никаких побочных эффектов, которыми не должно быть так или иначе). "Получить" префикс кажется лишним.

Я только что начал читать книгу "Чистый Код". Это говорит, что методы должны сделать только одну вещь, и что той вещью должно обычно быть одно из следующего:

  1. Уведомьте некоторый объект о событии, обычно передающем событие в качестве параметра.
  2. Задайте вопрос о некотором объекте, обычно с именем метода, формирующим оператор естественного языка, передав объект как параметр и возвратив булевскую переменную.
  3. Выберите что-то, возможно передав некоторый ключ поиска или некоторый объект, который будет преобразован как параметр и всегда возвращая требуемый объект / значение.

Мой вопрос о третьей категории. Есть ли соглашения о присвоении имен кроме, "добираются" для этого вида методов? Какие критерии Вы используете при выборе имен/префиксов метода?

Вот пример:

У меня есть класс с двумя методами getDates() и getSpecialDates(). getDates() просто возвращает значение частной переменной (ссылка на набор дат). Это - стандартный метод считывания, насколько я понимаю. getSpecialDates() отличается; это звонит getDates(), выбирает фильтр от другого класса, применяет фильтр и возвращает то, что является эффективно подмножеством getDates().

Метод getSpecialDates () можно было назвать computeSpecialDates(), findSpecialDates(), selectSpecialDates() или elicitSpecialDates() или что бы то ни было. Или я мог просто назвать его specialDates(). И затем, для непротиворечивости, я мог переименовать getDates() в dates().

Почему беспокойство, отделяющееся между методами, которые должны быть снабжены префиксом, "добирается" и методы, которые не должны, и почему беспокойство, находящее заменяющие слова для, "добирается"?

39
задан Mariusz Jamro 2 April 2013 в 09:27
поделиться

20 ответов

Важно, чтобы префикс "get" оставался, потому что:

  • метод должен указывать действие, поэтому он должен содержать глагол в своем имени

  • get показывает, что состояние переменная не изменится

  • насколько легко вы отличите метод account () от переменной account в этом выражении:

    newAccount = currentAccount + account () --- что делает этот account () ?


Причина, по которой вы видите слишком много геттеров в своем коде, должна вас беспокоить!

  • Либо вы разделяете свои классы на более мелкие, либо
  • просто лучше скрываете свой код, потому что вам не нужно раскрывать свои классы стажеров, и даже следует пытаться скрыть их как можно больше!
0
ответ дан 27 November 2019 в 02:20
поделиться

Я использую get и set только для методов, которые только получают или устанавливают свойство, но не многое другое.

0
ответ дан 27 November 2019 в 02:20
поделиться

Я думаю, это подмножество идеала "дайте вашим переменным и функциям осмысленные имена".

"get" имеет специфическое значение в Java Beans, как многие уже отметили. Поэтому я думаю, что его следует ограничить использованием для получения значения внутренней переменной, возможно, с побочными эффектами. Я думаю, что это допустимо, если "get" включает в себя незначительные вычисления, например, преобразование типа данных или извлечение значения из встроенного класса или переосмысление других значений, например, "public int getRightMargin() { return width-margin.left; }". Любые побочные эффекты должны быть ограничены тем, что действительно является "побочным эффектом" получения значения, например, установкой флага, который говорит, что значение было получено.

Но если есть серьезные вычисления, я не думаю, что это должно называться "get". Может быть, "calc" или как-нибудь еще.

Было бы хорошо, если бы у нас были единообразные термины для именования функций, например, если бы мы все согласились, что "read" означает, что основная деятельность заключается в получении чего-то из базы данных, а "calc" означает выполнение вычислений или что-то подобное. Но это может быть нереально: возможно, существует слишком много случаев с тонкими различиями.

1
ответ дан 27 November 2019 в 02:20
поделиться

Как многие уже отметили, get() и set()... являются частью Конвенции Java Beans. Это необходимо для взаимодействия с другими частями Java Spec. Например, в JSP вы можете получить доступ к членам Java bean, указав имя свойства без префикса get.

Учитывая боб: -

public class Foo {
  public int getX() { return 1; }
}

Мы можем сделать следующий JSP, чтобы получить X: -

<jsp:useBean id="aFoo" class="Foo" />
<c:out value="${aFoo.X}" />

Существуют ли другие соглашения об именовании, кроме "get", для такого рода методов?

Да, вы можете использовать is вместо get для булевых свойств.

3
ответ дан 27 November 2019 в 02:20
поделиться

Исторический фрагмент: если вы посмотрите на некоторые из самых ранних API Java 1.0 (до JavaBeans), вы увидите, что у них нет префикса get. Например, java.awt.Container # minimumSize () устарел и заменен на #getMinimumSize ().

1
ответ дан 27 November 2019 в 02:20
поделиться

Это происходит из соглашений об именах JavaBeans .

16
ответ дан 27 November 2019 в 02:20
поделиться

Одна из причин, которая требует от Java разработчиков использовать общее соглашение get/set, заключается в том, что многие фреймворки полагаются на него при создании bean и установке полей. Например, если у вас есть некоторое свойство, настроенное для Spring bean как и в классе нет метода с именем setFoo(), вы получите ошибку при создании bean.

4
ответ дан 27 November 2019 в 02:20
поделиться

Я начинаю чувствовать, что слово "получить" теряет смысл, потому что инфляции. Это шум в моем коде.

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

Для следующего примера:

Time.isoFormattedDateString(Date date)

Устанавливает ли это тип формата на основе входного параметра, чтобы все последующие вызовы использовали этот формат?

Я знаю, что кто-то придет к такому выводу с большой натяжкой. поскольку это статический метод, но были бы вы так же уверены, если бы этот метод был вызван на экземпляре? Возможно, но использование get устраняет всю двусмысленность:

getIsoFormattedDateString(Date date)

На мой взгляд, свойства - более элегантное решение, чем полное исключение get.

2
ответ дан 27 November 2019 в 02:20
поделиться

Java Beans очень привязаны к своим соглашениям об именах, например Предположим, вы объявляете имя переменной Name с соответствующим сеттером как setName (). Но это приведет к ошибке, поскольку setName должно соответствовать 'name' вместо Name. Другой пример логического isReadey; с получателем isReady (). Снова ошибка, поскольку он ищет готовое логическое значение. Итак, перед написанием кода вы должны ознакомиться с этим соглашением об именах. Но я лично предпочитаю это соглашение, так как оно упрощает работу программиста и кажется немного логичным после нескольких минут, проведенных с ним.

0
ответ дан 27 November 2019 в 02:20
поделиться

Лично я зависим от get. Это просто человеческий язык. Когда вы чего-то хотите, вы хотите получить что-то. Нет ничего плохого в префиксах get. Что касается соглашения об именовании, я могу вспомнить префикс Select для запросов к базе данных - SelectUsers, например.

2
ответ дан 27 November 2019 в 02:20
поделиться

Какое значение имеет значение "get", когда мы живем в эпоху, когда любая IDE, которую стоит иметь, будет генерировать геттеров и сеттеров для ваших частных переменных и позволит вам сложить их, если вы не хотите их читать?

Ваша реальная проблема должна быть связана с дизайном: почему ваши объекты имеют так много атрибутов? Если у ваших объектов нет ничего, кроме добытчиков и сеттеров, страдаете ли вы от «анемичной модели предметной области»?

Нотация C# {get, set} немного лучше, потому что она сокращает строки кода,но у вас все еще есть это надоедливое «получить», чтобы набрать для каждой переменной.

3
ответ дан 27 November 2019 в 02:20
поделиться

Одна из причин в том, что это существенная часть Java Bean Spec.

5
ответ дан 27 November 2019 в 02:20
поделиться

Отчасти причина большого количества методов get* заключается в том, что Java не поддерживает "свойства" в стиле .net/COM, а Java-бобы и подобные им используют функции getX и setX для воспроизведения функциональности свойства под названием X. Некоторые IDE для Java пользуются этим, чтобы позволить устанавливать и извлекать свойства.

9
ответ дан 27 November 2019 в 02:20
поделиться

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

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

В Effective Java Джошуа Блох дает такую ​​убедительную рекомендацию:

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

В той же книге он также говорит (но я не хочу копировать здесь всю книгу):

В шаблоне JavaBeans есть серьезные недостатки.

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

27
ответ дан 27 November 2019 в 02:20
поделиться

Ну, хотя спецификация JavaBeans просит вас объявить геттеры и сеттеры, я обычно не объявляю их, если это не является абсолютно необходимым (как в случае многих MVC фреймворков). Я много занимался свингом в своей карьере Java и склонен объявлять переменные как public (да, это звучит немного не OOPy). Но мне это нравилось, поскольку выглядело лаконично, и "я" знал, что я делаю. Единственное преимущество, которое он имел - это уменьшенное количество строк.

0
ответ дан 27 November 2019 в 02:20
поделиться

Имена методов, например getSpecialDates () , computeSpecialDates () , findSpecialDates () , selectSpecialDates () и () для меня это команды из-за использования в их именах глаголов (действий). Команды должны вызывать побочные эффекты каждый раз, когда вы их вызываете. В то время как имена методов, такие как date () , date () , specialDates () [существительные], являются методами, которые возвращают полезное значение без побочных эффектов. Вызов метода несколько раз возвращает одно и то же значение каждый раз, если только не вызывается команда, побочным эффектом которой является изменение состояния.

5
ответ дан 27 November 2019 в 02:20
поделиться

Одна из причин того, что методы getter и setter часто пишутся в Java, заключается в использовании JavaBeans конвенций.

Однако стандартный API Java не является последовательным в этом отношении. Например, класс String имеет метод length(), а интерфейс Collection определяет метод size(), вместо getLength() или getSize().

Java не поддерживает принцип единообразного доступа, поэтому для доступа к свойствам нужно писать методы getter и setter.

6
ответ дан 27 November 2019 в 02:20
поделиться

Один из вариантов - сохранить префикс get для методов, возвращающих примитивные или неизменяемые значения, но убрать префикс для методов, возвращающих ссылки, которые могут быть использованы для изменения исходного получателя.

например, в java.util.Map, size() может называться getSize(), но keySet() будет не называться getKeySet().

1
ответ дан 27 November 2019 в 02:20
поделиться

Как упоминали другие, это для Java Beans. Однако, если вы используете Java, ПОЖАЛУЙСТА, назовите метод getXXX() только в том случае, если он возвращает только значение и больше ничего не делает. Как вы намекнули, если он делает что-то другое, назовите это чем-то другим, например, computeXXX().

Я иногда нахожу методы getXXX() с 50 строками кода - если это так, вы делаете это неправильно.

3
ответ дан 27 November 2019 в 02:20
поделиться

Предпосылка 1. Метод должен делать только одно. Предпосылка 2: метод получения - независимо от того, использует он префикс get или нет - не должен иметь побочных эффектов. С учетом этих двух предпосылок я предлагаю: метод, роль которого заключается в получении чего-либо и который делает это относительно простым и недорогим способом, не должен иметь в названии глагола.

Смысл существования добытчика не в том, чтобы что-то делать, а в том, чтобы что-то оценить. Нас не интересует, что делает метод . Поскольку он не имеет побочных эффектов, любые вычисления, выполняемые в методе, не могут представлять интереса. Нас интересует только то, что возвращает метод . Название метода должно отражать это в форме существительного. Имена методов, состоящие только из существительных, всегда должны быть «геттерами».

Информация в префиксе «получить» может быть выведена из-за отсутствия глаголов. Это проще и интуитивно понятнее, чем использование префикса get.

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

Похоже, что причина, по которой все повсюду пишут "получить", является просто догматической традицией, происходящей из шаблона JavaBeans. Оставьте префикс get, если вы действительно планируете использовать инструменты / фреймворки, которые в этом нуждаются!

3
ответ дан 27 November 2019 в 02:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: