Рекомендации по использованию интерфейса Java — Плохи ли геттеры и сеттеры в интерфейсе?

StackOverflow https://stackoverflow.com/questions/1130294

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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


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

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

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


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

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

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
}

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

private Size size;

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

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

public Size getSize() {
    return size;
}

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

В геттерах/сеттерах нет ничего злого по своей сути.Однако:

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

Это все рекомендации, заметьте.

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

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

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

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

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

Принимая это во внимание, нет ничего плохого - синтаксически и семантически - в наличии сеттеров и геттеров в интерфейсах.

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

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

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

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

Это затрагивает всю тему «Геттеры/сеттеры — злая тема», которая неоднократно обсуждалась на этом сайте и в других местах.

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

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

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

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

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

List.size() из Джона выше — прекрасный пример метода получения, который необходимо определить в интерфейсе.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top