Allen Holub записал, что “Вы никогда не должны использовать, добираются/функции множества”, он корректен? [дубликат]

Я только что наткнулся на этот вопрос и должен был опубликовать ответ. ИМО, это очевидный случай использования API отражения Java

DiscriminatorValue annotation = ApplicationProcess.class.getAnnotation(DiscriminatorValue.class);
annotation.getValue().equals("AP");
50
задан Community 23 May 2017 в 01:53
поделиться

12 ответов

У меня нет проблем с тем, что Голуб говорит вам, что вам обычно следует избегать изменения состояния объекта, а вместо этого прибегать к интегрированным методам (выполнение поведения), чтобы достичь этой цели. Как указывает Корлетк, есть мудрость в том, чтобы долго и усердно думать о высочайшем уровне абстракции, а не просто бездумно программировать с помощью геттеров / сеттеров, которые просто позволяют вам в конце концов обойти инкапсуляцию.

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

Голуб не верит, что вы знаете разницу. Я думаю, что знание разницы - вот что делает вас профессионалом.

38
ответ дан 7 November 2019 в 10:35
поделиться

Ummmm...has he never heard of the concept of Encapsulation. Getter and Setter methods are put in place to control access to a Class' members. By making all fields publicly visible...anybody could write whatever values they wanted to them thereby completely invalidating the entire object.

Just in case anybody is a little fuzzy on the concept of Encapsulation, read up on it here:

Encapsulation (Computer Science)

...and if they're really evil, would .NET build the Property concept into the language? (Getter and Setter methods that just look a little prettier)

EDIT

The article does mention Encapsulation:

"Getters and setters can be useful for variables that you specifically want to encapsulate, but you don't have to use them for all variables. In fact, using them for all variables is nasty code smell."

Using this method will lead to extremely hard to maintain code in the long run. If you find out half way through a project that spans years that a field needs to be Encapsulated, you're going to have to update EVERY REFERENCE of that field everywhere in your software to get the benefit. Sounds a lot smarter to use proper Encapsulation up front and safe yourself the headache later.

0
ответ дан 7 November 2019 в 10:35
поделиться

Я не верю, что он говорит, что никогда не используйте get / set, а скорее, что использование get / set для поля не лучше, чем просто сделать поле общедоступным (например, публичное имя строки vs. общедоступное строка Имя {get; set;}).

Использование get / set ограничивает скрытие информации OO, что потенциально может заблокировать вас в плохом интерфейсе.

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

Однако, если вместо использования get / set у вас изначально был такой метод, как Add (имя строки), вы могли бы обрабатывать имя по отдельности или добавлять в список или что-то еще, а извне вызывать метод Add столько раз, сколько вы хотите добавить больше имен.

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

Скорее всего, если вы только что обернули примитивный тип с помощью get / set, вы нарушили этот принцип.

Конечно, это если вы верите в цели ОО; Я считаю, что в большинстве случаев это не так, они просто используют объекты как удобный способ группировки функционального кода.

2
ответ дан 7 November 2019 в 10:35
поделиться

(заметьте, я исхожу из точки зрения .NET "свойства")

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

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

Аксессоры не деталь реализации; это публичный API / контракт. Ага, если вы нарушите договор, у вас будут проблемы. Когда это стало сюрпризом? Точно так же аксессоры нередко бывают нетривиальными, т.е. они делают больше, чем просто переносят поля; они выполняют вычисления, логические проверки, уведомления и т. д. И они позволяют абстракции состояния на основе интерфейса. Да, и полиморфизм и т. Д.

Относительно подробного характера методов доступа (p3? 4?) - в C #: public int Foo {get; private set;} - работа выполнена.

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

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

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

10
ответ дан 7 November 2019 в 10:35
поделиться

I think what Allen Holub tried to say, rephrased in this article, is the following.

Getters and setters can be useful for variables that you specifically want to encapsulate, but you don't have to use them for all variables. In fact, using them for all variables is nasty code smell.

The trouble programmers have, and Allen Holub was right in pointing it out, is that they sometimes use getters/setters for all variables. And the purpose of encapsulation is lost.

31
ответ дан 7 November 2019 в 10:35
поделиться

Внимательно прочтите эту статью. Голуб настаивает на том, что геттеры и сеттеры - это злой «антипаттерн по умолчанию», дурная привычка, которой мы уклоняемся при проектировании системы; потому что мы можем.

Мыслительный процесс должен быть в соответствии с принципами; Что делает этот объект ? Каковы его обязанности? Каково его поведение? Что он знает? Думать долго и упорно на эти вопросы ведет вас, естественно, в направлении проектирования классов, открывающие самого высокоуровневого интерфейса возможно.

Автомобиль является хорошим примером. Он предоставляет четко определенный стандартизованный высокоуровневый интерфейс. Меня не интересует setSpeed ​​(60) ... это миль / ч или км / ч? Я просто ускоряюсь, круизу, замедляю. Я не исходя из опыта, для чего используется этот класс, вы, вероятно, захотите вернуться и очистить грязный низкоуровневый интерфейс. Рефакторинг, основанный на «вещах, которые вы хотели бы знать, когда писали отстой», является нормой для курса. Вам не нужно знать все, чтобы начать, просто чем больше вы знаете, тем меньше переделок, вероятно, потребуется на пути.

Это менталитет, который он продвигает. Геттеры и сеттеры - это ловушка, в которую легко попасть.

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

daisy.setColor (Color.PINK) имеет смысл. Что еще можно сделать? Может быть, вулканское слияние разумов, чтобы цветок хотел быть розовым? Хммм?

У геттеров и сеттеров есть свое? Зло? место. Просто, как и все действительно хорошие ОО-вещи, мы склонны злоупотреблять ими, потому что они безопасны и знакомы, не говоря уже о простых, и поэтому было бы лучше, если бы новички не видели и не слышали о них, по крайней мере, пока они не ' Я овладел идеей слияния разума.

32
ответ дан 7 November 2019 в 10:35
поделиться

Геттеры и сеттеры используются как не более чем маска, чтобы сделать частную переменную общедоступной.

В этом нет смысла. повторяя то, что уже сказал Голуб, но суть в том, что классы должны представлять поведение, а не только состояние.

9
ответ дан 7 November 2019 в 10:35
поделиться

Я дополнительно погуглил Аллена Холуба, похоже, у него есть свои противники в сообществе Java.

Последний особенно отмечен. Текст комментатора выделен курсивом.

Хотя getIdentity начинается с «get», это не средство доступа, потому что оно не просто возвращает поле. Он возвращает сложный объект с разумным поведением

Ой, но подождите ... тогда можно использовать аксессоры, если вы возвращаете объекты вместо примитивных типов? Теперь это другая история, но для меня это так же глупо. Иногда вам нужен объект, иногда вам нужен примитивный тип.

Кроме того, я заметил, что Аллен радикально смягчил свою позицию после его предыдущей колонки по той же теме, где мантра «Никогда не используйте аксессоры» не страдала ни одним исключением. Может быть, через несколько лет он понял, что аксессоры в конце концов служат определенной цели ...

Имейте в виду, что я на самом деле не вставлял код UI в бизнес-логику. Я написал уровень пользовательского интерфейса в терминах AWT (Abstract Window Toolkit) или Swing, которые являются уровнями абстракции.

Хороший. Что делать, если вы пишете свое приложение на SWT? Насколько «абстрактным» в таком случае является AWT? Признайтесь: этот совет просто приводит вас к написанию кода пользовательского интерфейса в своей бизнес-логике. Какой отличный принцип. В конце концов, прошло не менее десяти лет с тех пор, как мы определили эту практику как одно из худших дизайнерских решений, которые вы можете принять в проекте.

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

8
ответ дан 7 November 2019 в 10:35
поделиться

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

0
ответ дан 7 November 2019 в 10:35
поделиться

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

Геттеры и сеттеры имеют смысл, когда они отражают какую-то связную идею. В классе многоугольника, например, координаты x и y заданных вершин имеют значение за пределами границ класса. Вероятно, имеет смысл иметь геттеры и, вероятно, имеет смысл иметь сеттеры. В классе банковских счетов баланс, вероятно, хранится как частная переменная и почти наверняка должен иметь получатель. Если у него есть сеттер, он должен иметь встроенное ведение журнала для сохранения возможности аудита.

Есть некоторые преимущества геттеров и сеттеров перед общедоступными переменными. Они обеспечивают некоторое разделение интерфейса и реализации. Тот факт, что точка имеет функцию .getX () , не означает, что должен быть x, поскольку .getX () и .setX () можно заставить нормально работать с радиальными координатами. Другой заключается в том, что можно поддерживать инварианты классов, делая все необходимое для сохранения согласованности класса в установщике. Во-вторых, можно иметь функциональность, которая запускается по набору, например, ведение журнала баланса банковского счета.

Однако для более абстрактных классов переменные-члены теряют индивидуальную значимость и имеют смысл только в контексте. Ты не Например, мне нужно знать все внутренние переменные класса потока C ++. Вам нужно знать, как вводить и выводить элементы и как выполнять различные другие действия. Если бы вы рассчитывали на точную внутреннюю структуру, вы бы увязли в деталях, которые могут произвольно различаться между компиляторами или версиями.

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

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

2
ответ дан 7 November 2019 в 10:35
поделиться

Открытые геттеры / сеттеры плохи, если они предоставляют доступ к деталям реализации. Тем не менее, разумно предоставить доступ к свойствам объекта и использовать для этого геттеры / сеттеры. Например, если Car имеет свойство color, можно позволить клиентам «наблюдать» за ним с помощью геттера. Если какому-то клиенту нужна возможность перекрасить автомобиль, класс может предоставить установщик (хотя «перекрасить» - более понятное название). Важно не сообщать клиентам, как свойства хранятся в объектах, как они поддерживаются и т. Д.

1
ответ дан 7 November 2019 в 10:35
поделиться

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

Например, хотя некоторые не согласятся, мне нравится Java Standard API. Мне также нравится Spring Framework. Глядя на классы в этих библиотеках, вы заметите, что очень редко есть сеттеры и геттеры, которые существуют только для того, чтобы предоставить некоторую внутреннюю переменную. Существуют методы с именем getX, но это не означает, что это геттер в общепринятом смысле.

Итак, я думаю, что он прав, и вот что: каждый раз, когда вы нажимаете кнопку «Создать геттеры / сеттеры» в Eclipse (или в вашей IDE по своему выбору), вы должны сделать шаг назад и задуматься о том, что вы делаете. . Действительно ли уместно раскрывать это внутреннее представление, или я на каком-то этапе испортил свой дизайн?

5
ответ дан 7 November 2019 в 10:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: