Соглашения об именах методов Java: слишком много получателей - PullRequest
39 голосов
/ 09 июля 2010

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

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

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

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

Мой вопрос касается третьей категории.Существуют ли соглашения об именах, отличные от «get», для таких методов?Какие критерии вы используете при выборе имен / префиксов методов?

Вот пример:

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

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

Зачем беспокоиться о разделении между методами, которые должны иметь префикс «get», и методами, которые не должны, и зачем искать слова для замены для «получить "?

Ответы [ 20 ]

27 голосов
/ 09 июля 2010

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

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

В Эффективная Java Джошуа Блох делает эту убедительную рекомендацию:

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

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

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

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

16 голосов
/ 09 июля 2010
9 голосов
/ 09 июля 2010

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

6 голосов
/ 09 июля 2010

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

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

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

5 голосов
/ 12 июля 2010

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

5 голосов
/ 09 июля 2010

Одна из причин заключается в том, что она является неотъемлемой частью спецификации Java Bean .

4 голосов
/ 09 июля 2010

Одна из причин, по которой разработчики Java должны использовать общее соглашение get / set, заключается в том, что многие фреймворки используют его для создания бинов и установки полей. Например, если у вас настроено какое-то свойство для bean-компонента Spring, например <property name="foo" value="bar" />, и в классе нет метода с именем setFoo(), вы получите ошибку при создании bean-компонента.

3 голосов
/ 09 июля 2010

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

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

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

3 голосов
/ 09 июля 2010

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

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

3 голосов
/ 13 июля 2010

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

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

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

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

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

...