Подтвердить что ты не робот

Рекомендации по использованию интерфейса Java. Неужели получатели и сеттеры в интерфейсе плохо?

Что люди думают о лучших рекомендациях по использованию в интерфейсе? Что нужно и не должно входить в интерфейс?

Я слышал, что люди говорят, что, как правило, интерфейс должен определять поведение, а не состояние. Означает ли это, что интерфейс не должен содержать геттеры и сеттеры?

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

4b9b3361

Ответ 1

Я думаю, что есть два типа интерфейсов, объявленных вообще:

  • a описание службы. Это может быть что-то вроде CalculationService. Я не думаю, что методы getX должны быть в этом виде интерфейса и, конечно, не setX. Они довольно четко подразумевают детали реализации, что не является задачей этого типа интерфейса.
  • a модель данных - существует только для абстрагирования реализации объектов данных в системе. Они могут использоваться для тестирования или просто потому, что некоторые старые люди, как я помню, когда (например) использовали платформу персистентности, привязали вас к определенным суперклассам (т.е. Вы решили реализовать интерфейс в случае, если вы переключились ваш уровень персистентности). Я думаю, что наличие методов JavaBean в этом типе интерфейса вполне разумно.

Примечание: классы коллекций, вероятно, подходят для типа # 2

Ответ 2

Я не понимаю, почему интерфейс не может определить геттеры и сеттеры. Например, List.size() эффективно является геттером. Интерфейс должен определять поведение, а не реализацию, хотя он не может сказать, как вы будете обрабатывать состояние, но он может настаивать на том, что вы можете его получить и установить.

Интерфейсы коллекции - все о состоянии, например, - но разные коллекции могут сохранять это состояние по-разному.

EDIT: комментарии показывают, что геттеры и сеттеры подразумевают, что для резервного хранилища используется простое поле. Я категорически не согласен с этим. На мой взгляд, подразумевается, что "разумно дешево" получить/установить значение, но не то, что оно хранится как поле с тривиальной реализацией.


EDIT: как отмечено в комментариях, это явно указано в спецификации JavaBeans в разделе 7.1:

Таким образом, даже когда типы типов scriptв чем-то вроде b.Label = fooвсе еще есть вызов метода в целевой объект для установки свойства и целевой объект имеет полный программный контроль.

Таким образом, свойства должны быть не просто простыми полей данных, они могут фактически быть вычисленные значения. Обновления могут иметь различные программные побочные эффекты. Для например, изменение фона beanсвойство цвета также может привести к bean, чтобы перекрасить с помощью нового цвет ".


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

Например, рассмотрим компонент с

getWidth()
getHeight()
getSize()

Считаете ли вы, что там есть три переменные? Было бы разумно либо:

private int width;
private int height;

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public Size getSize() {
    return new Size(width, height); // Assuming an immutable Size type
}

Или (предпочтительнее ИМО):

private Size size;

public int getWidth() {
    return size.getWidth();
}

public int getHeight() {
    return size.getHeight();
}

public Size getSize() {
    return size;
}

Здесь либо свойство размера, либо свойства height/width предназначены только для удобства - но я не вижу, что это делает их некорректными.

Ответ 3

Там нет ничего злонамеренного в отношении геттеров/сеттеров. Однако:

  • Я стараюсь сделать мои объекты неизменными (в первом случае) относительно полей, которые они содержат. Зачем? Я создаю экземпляр большинства вещей на этапе строительства. Если я хочу что-то изменить, я ослаблю эти ограничения. Таким образом, мои интерфейсы будут содержать геттеры, но не сеттеры (есть другие преимущества, в частности, потоки).
  • Я хочу, чтобы мои объекты делали что-то для меня, а не наоборот. Поэтому, когда один из моих объектов приобретает несколько геттеров, я начинаю спрашивать, должен ли этот объект иметь больше функциональности в нем, а не обнажать все его данные для чего-то другого, с которым можно работать. Подробнее см. этот ответ.

Все эти рекомендации, обратите внимание.

Ответ 4

Я не думаю, что bean должен иметь интерфейс поверх него, в общем. Javabean - это интерфейс в более общем смысле. Интерфейс определяет внешний контракт над чем-то более сложным. Наружный контракт javabean и его внутреннее представление идентичны.

Я бы не сказал, что у вас не должно быть геттеров в интерфейсе. Имеет смысл иметь интерфейс ReadableDataThingie, который реализуется DataThingieBean.

Ответ 5

Это касается всего Getter/Setters - это злая тема, которая неоднократно рассматривается на этом сайте и в других местах.

Я склоняюсь к тому, что у меня нет помощников в интерфейсе, но для добавления коллабораторов с использованием аргументов конструктора в реализацию.

Ответ 6

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

Ответ 7

Я слышал, что люди говорят, что, как общее правило, интерфейс должен определить поведение, а не состояние. Есть ли это означает, что интерфейс не должен содержат геттеры и сеттеры?

Для начала, по крайней мере, с Java и исключения исключений Exception, вы не можете определить полное поведение без состояния. В Java интерфейсы не определяют поведение. Они не могут. То, что они определяют, это типы; promises реализации набора сигнатур функций, возможно, с некоторыми исключениями после условий. Но это так. Поведение и состояние определяются классами, реализующими эти интерфейсы.

Во-вторых, если геттеры и сеттеры определены в интерфейсе, они на самом деле не определяют полное поведение (другое, что одно для чтения, а одно - для записи по свойству.) У вас может быть сложное поведение за сеттерами и геттерами, но они могут быть реализованы только в реальных классах. На языке Java нет ничего, что могло бы позволить нам свободно определять поведение в интерфейсах, за исключением самых ограничительных случаев.

С учетом этого нет ничего неправильного - синтаксически и семантически - с установками и геттерами в интерфейсах.

Если ваше приложение хорошо смоделировано, и проблема требует, чтобы у вас был интерфейс, определяющий сеттеры и геттеры, почему бы и нет. Например, взгляните на интерфейс ServletResponse.

Теперь, если мы посмотрим на геттеры и сеттеры с точки зрения реализации классов, соответствующих спецификациям JavaBeans, тогда вам не нужно определять интерфейсы для них.

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

Надеюсь, что это поможет.

Ответ 8

Для дальнейшего чтения: Практические API Design Confessions архитектора Java Framework (Ярослав Тулач, 2008, Apress).

Ответ 9

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

Ответ 10

В принципе, если ответ на вопрос "Нужно ли мне знать значение [state, property, whateverThignAMaGit], чтобы работать с его экземпляром?" то да... аксессоры принадлежат интерфейсу.

List.size() от Джона выше - прекрасный пример геттера, который должен быть определен в интерфейсе

Ответ 11

Getters используются для запроса состояния объекта, чего вы действительно можете избежать при разработке интерфейса. Прочитайте http://www.pragprog.com/articles/tell-dont-ask