Методы считывания и Методы set являются плохим дизайном OO? [дубликат]

26
задан Julio 14 November 2010 в 02:34
поделиться

11 ответов

Геттеры или сеттеры сами по себе не являются плохим ОО дизайном.

Что плохо, так это практика кодирования, которая включает геттер и сеттер для КАЖДОГО члена автоматически, независимо от того, нужен ли этот геттер/сеттер или нет (в сочетании с тем, что члены, которые не должны быть публичными, делаются публичными) - потому что это, по сути, раскрывает реализацию класса внешнему миру, нарушая скрытие информации/абстракцию. Иногда это делается автоматически в IDE, что означает, что такая практика значительно более распространена, чем хотелось бы.

33
ответ дан 28 November 2019 в 06:04
поделиться

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

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

3
ответ дан 28 November 2019 в 06:04
поделиться

Вы упустили суть. Действительный и важный фрагмент этой статьи:

Не запрашивайте информацию, которая вам нужна для выполнения работы; спросите у объекта, что у есть информация, которая поможет вам .

Распространение геттеров и сеттеров в стиле Java является симптомом игнорирования этого совета.

51
ответ дан 28 November 2019 в 06:04
поделиться

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

1
ответ дан 28 November 2019 в 06:04
поделиться

Геттеры и сеттеры - плохой объектно-ориентированный дизайн?

Только когда используются не задумываясь.

Если вы создаете объект-значение для передачи данных, они в порядке.

Если вы создаете более важный объект, то их там не должно быть. Взгляните, например, на интерфейс ArrayList * . Вы не видите Object [] getElementData () , потому что это нарушит инкапсуляцию (кто-то может изменить базовый массив).

* Я имею в виду открытый интерфейс класса (методы, указанные в определении класса)

0
ответ дан 28 November 2019 в 06:04
поделиться

Есть и другие статьи, в которых говорится, что это хороший дизайн. Но ответ таков: getXXX и setXXX хороши или плохи в зависимости от использования. Эти матоды действительно облегчают многие вещи. Так что если в какой-то статье говорится, что это плохой дизайн, я думаю, что это просто попытка слишком жестко подойти к идее.

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

Так что не стоит полностью избегать их использования, скорее... используйте их разумно.

спасибо Ayusman

0
ответ дан 28 November 2019 в 06:04
поделиться

Геттеры/сеттеры вполне уместны в правильных условиях. Однако массовый Get/Set - это неправильно.

Однако, я немного запутался. Вы отметили Java, но материал не особенно специфичен для Java (только примеры). Стоит отметить, что в C++ (лучше всего в 0x) многие из этих проблем не существуют. Если вы хотите изменить свой интерфейс с long на int, то между decltype, шаблонами и auto это легко достижимо, именно поэтому такие конструкции - рок. Typedef тоже хорошо работает.

0
ответ дан 28 November 2019 в 06:04
поделиться

Из статьи:

Когда можно использовать аксессуар? Во-первых, как я обсуждал ранее, для метода нормально возвращать объект в терминах интерфейса, который реализует объект , потому что этот интерфейс {{ 1}} изолирует вас от изменений в классе реализации . Этот вид метода (который возвращает ссылку на интерфейс ) на самом деле не является "получателем" в смысле метода, который просто предоставляет доступ к поле. Если вы меняете внутреннюю реализацию провайдера, вы просто меняете определение возвращаемого объекта , чтобы учесть эти изменения. Вы по-прежнему защищаете внешний код, который использует объект через свой интерфейс.

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

0
ответ дан 28 November 2019 в 06:04
поделиться

Я верю во включение сеттеров в API, только если они действительно являются частью спецификации класса (т.е. его контракта с вызывающей стороной).

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

1) Если внутреннее представление открыто, изменения в дизайне будут более проблематичными в будущем и потребуют изменений в API.

2) Раскрытие членов данных с сеттерами/геттерами без всякой осторожности позволяет вызывающим пользователям очень легко нарушить инвариантность класса. Объекты с непоследовательным состоянием могут вызывать ошибки, которые очень трудно анализировать.

К сожалению, есть некоторые фреймворки, которые поощряют (иногда требуют) добавлять сеттеры/геттеры для всего.

5
ответ дан 28 November 2019 в 06:04
поделиться

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

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

Url.setAnchor (...)

Возвращает новый URL, копируя порт хоста и т. Д., Но перезаписывая якорь.

Вашим классам типов услуг не нужны сеттеры (установите их в ctor), и определенно шрифтам нужны геттеры. Ваш почтовый клиент должен принимать статические данные хоста / порта / и т. Д. В своем ctor. Если я хочу отправить электронное письмо, я помещаю его в ячейку send (), нет причин, по которым мой код должен знать или требовать или требовать хост и другие значения конфигурации. При этом имеет смысл создать класс MailServer, подобный следующему // тип значения MsilServer { String host int port String имя пользователя Врезанный пароль // все приходят получатели рута } // factory Mailer create (MailServer)

2
ответ дан 28 November 2019 в 06:04
поделиться

Геттеры и сеттеры - это просто методы. Что они делают? Они превращают поле в свойство, и это важное различие.

Поле - это бит данных состояния в объекте. Собственность - это внешне наблюдаемая характеристика, часть контракта на объект. Распылять внутренности объекта повсюду, напрямую или через геттеры / сеттеры, всегда плохая идея. Плохой дизайн. Но довести это до такой степени, чтобы сказать, что геттеры и сеттеры всегда плохи? Это просто какой-то плохой программист без чувства хорошего вкуса, утверждающий, что расплывчатое эмпирическое правило (которое они изначально не понимали) - это чугунный закон.

Лично я стараюсь сохранить свойства как вещи, которые не меняются неожиданно под ногами клиентов. (Клиенты того класса, который есть.) Единственные свойства, которые я изменяю динамически, - это те, которые они не могут записать, и даже тогда я постараюсь этого избежать. Я чувствую, что свойства во многих отношениях являются значениями, которые управляют поведением экземпляра, которые устанавливаются клиентом, а не произвольными вещами, находящимися под контролем класса. (Это обычное поле для ...)

1
ответ дан 28 November 2019 в 06:04
поделиться