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

Геттеры и сеттеры плохие

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

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

Спасибо.


person Julio    schedule 30.04.2010    source источник
comment
Взгляните на stackoverflow.com/questions/ 565095 / и принятый ответ.   -  person Don Roby    schedule 01.05.2010
comment
Интересная статья, но -1 как статья объясняет ответ на ваш вопрос.   -  person Martin Smith    schedule 01.05.2010
comment
Ссылки по теме: c2.com/cgi/wiki?AccessorsAreEvil, c2.com/cgi/wiki?ForgetAboutWritingAccessors, c2.com/cgi/wiki?TellDontAsk   -  person Seth    schedule 01.05.2010
comment
Мне очень нравится многое из вещей Аллена. Временами он может быть неуклюжим, но он умеет указывать на подобные вещи. Поищите на его сайте дополнительные сведения: holub.com   -  person Bill K    schedule 01.05.2010


Ответы (13)


Сами по себе геттеры или сеттеры - неплохой объектно-ориентированный дизайн.

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

person DVK    schedule 30.04.2010

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

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

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

person Cory Petosky    schedule 30.04.2010
comment
Это возможный симптом. Возможно также, что проблема просто не поддается решению таким образом. Или они могут быть симптомом использования внедрения зависимостей. - person Stephen C; 01.05.2010

Да, геттеры и сеттеры - это анти-шаблон в ООП: http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html. Короче говоря, они не вписываются в объектно-ориентированную парадигму, потому что побуждают вас рассматривать объект как структуру данных. Это серьезное заблуждение.

person yegor256    schedule 16.09.2014

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

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

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

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

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

person Eyal Schneider    schedule 30.04.2010

Геттеры и сеттеры сами по себе неплохи. Плохо то, что любое поле становится частным и предоставляет геттеры / сеттеры для всех, несмотря ни на что.

person fastcodejava    schedule 31.10.2010

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

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

person Krumelur    schedule 30.04.2010
comment
Более того, посмотрите на ответ Кори Петоски, это просто плохой способ обработки информации. Если вы просите объект выполнить операцию над внутренними переменными, то где же в этом миксе могут быть сеттер или геттер? - person Bill K; 01.05.2010

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

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

Url.setAnchor (...)

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

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

person mP.    schedule 01.05.2010

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

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

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

person Donal Fellows    schedule 01.05.2010

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

person Tom Cabanski    schedule 30.04.2010

Из статьи:

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

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

person Matthew Sowders    schedule 30.04.2010
comment
Совершенно неправильно, что ваши классы работы должны предоставлять свою конфигурацию через геттеры. - person mP.; 01.05.2010

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

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

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

спасибо аюсман

person Ayusman    schedule 01.05.2010

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

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

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

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

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

person OscarRyz    schedule 01.05.2010

Геттеры / сеттеры идеально подходят в подходящих условиях. Однако массовое получение / установка неверно.

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

person Puppy    schedule 01.05.2010