Я использую следующие два плагина все время:
Это вопрос "передовой практики" и стиля.
Кроме того, существует проблема повторного использования. Скажем, в будущем вам нужно изменить то, что происходит, когда кто-то обращается к члену данных. Вы можете сделать это, не заставляя клиентов перекомпилировать код. Вы можете просто изменить метод в классе и гарантировать использование новой логики.
Геттеры / сеттеры, конечно, являются хорошей практикой, но их утомительно писать и, что еще хуже, читать.
Сколько раз мы читали класс с полдюжиной членов переменные и сопутствующие геттеры / сеттеры, каждый из которых имеет полный код hog @ param / @ return HTML, известный бесполезный комментарий вроде «получить значение X», «установить значение X», «получить значение Y», «установить значение Y ',' получить значение Z ',' установить значение Zzzzzzzzzzzzz. бац!
Я согласен с вами, но важно выжить в системе. В школе сделайте вид, что согласен. Другими словами, уценка вредна для вас, и ее не стоит понижать из-за ваших принципов, мнений или ценностей.
Кроме того, работая в команде или у работодателя, делайте вид, что согласны. Позже начните собственное дело и делайте это по-своему. Пока вы пробуете пути других, будьте спокойны и непредубеждены по отношению к ним - вы можете обнаружить, что этот опыт меняет ваши взгляды.
Инкапсуляция теоретически полезна в случае, если внутренняя реализация когда-либо изменится. Например, если URL-адрес для каждого объекта стал вычисленным результатом, а не сохраненным значением, то инкапсуляция getUrl () продолжила бы работать. Но я подозреваю, что вы уже слышали об этом.
Одна из проблем, с которой сталкивается индустрия программного обеспечения, - это проблема многократно используемого кода. Это большая проблема. В мире аппаратного обеспечения компоненты оборудования проектируются один раз, затем конструкция повторно используется позже, когда вы покупаете компоненты и собираете их вместе для создания новых вещей.
В мире программного обеспечения каждый раз, когда нам нужен компонент, мы проектируем его снова и снова. . Это очень расточительно.
Инкапсуляция была предложена как метод обеспечения возможности повторного использования создаваемых модулей. То есть существует четко определенный интерфейс, который абстрагирует детали модуля и упрощает использование этого модуля в дальнейшем. Интерфейс также предотвращает неправильное использование объекта.
Простые классы, которые вы создаете в классе, неадекватно иллюстрируют необходимость четко определенного интерфейса. Говоря "Но почему бы и нет?"
Как разработчик C ++ я делаю своих участников всегда закрытыми, просто чтобы быть последовательным. Так что я всегда знаю, что мне нужно набирать px (), а не px
Кроме того, я обычно избегаю реализации методов установки. Вместо изменения объекта я создаю новый:
p = Point(p.x(), p.y() + 1);
Это также сохраняет инкапсуляцию.
В какой-то момент инкапсуляция становится нелепой.
Чем больше абстракций вводится в код, тем выше будет ваше предварительное образование, затраты на обучение будут.
Каждый, кто знает C, может отладить ужасно написанную функцию из 1000 строк, которая использует только стандартную библиотеку базового языка C. . Не каждый может отлаживать придуманный вами фреймворк. Каждая введенная инкапсуляция / абстракция уровня должна быть сопоставлена со стоимостью. Это не значит, что оно того не стоит, но, как всегда, вы должны найти оптимальный баланс для вашей ситуации.
Возможно, оба варианта немного неверны, потому что ни одна из версий класса не имеет поведения. Сложно комментировать дальше без дополнительного контекста.
См. http://www.pragprog.com/articles/tell-dont-ask
Теперь давайте представим, что ваш класс FeedItem
имеет стали невероятно популярными и используются проектами повсеместно. Вы решаете, что вам нужно (как предлагали другие ответы) проверить предоставленный URL.
Счастливые дни, вы написали установщик для URL. Вы редактируете его, проверяете URL-адрес и генерируете исключение, если оно недействительно. Вы выпускаете новую версию класса, и все, кто ее использует, довольны. (Давайте проигнорируем отмеченные и непроверенные исключения, чтобы не сбиться с пути.)
Кроме того, тогда вам позвонит сердитый разработчик. Они читали список элементов ленты из файла при запуске своего приложения. А теперь, если кто-то допустит небольшую ошибку в файле конфигурации, выдается новое исключение и вся система не запускается только потому, что один чертов элемент фида был неправильным!
Возможно, вы сохранили подпись метода такой же, но вы изменили семантику интерфейса, поэтому он нарушает зависимый код. Теперь вы можете либо взять верх и сказать им, чтобы они правильно переписали свою программу, либо скромно добавьте setURLAndValidate
.
setURLAndValidate
. но вы изменили семантику интерфейса, поэтому он нарушает зависимый код. Теперь вы можете либо взять верх и сказать им, чтобы они правильно переписали свою программу, либо скромно добавьте setURLAndValidate
. Если что-то представляет собой простую структуру, тогда да, это смешно, потому что это просто ДАННЫЕ.
На самом деле это просто возврат к началу ООП, где люди до сих пор не поняли идеи классов вообще. Нет причин иметь сотни методов get и set на случай, если вы когда-нибудь измените getId () на удаленный вызов телескопа Хаббла.
Вам действительно нужна эта функциональность на ВЕРХНЕМ уровне, внизу она бесполезна . IE, у вас будет сложный метод, которому для работы был отправлен чистый виртуальный класс, гарантирующий, что он все еще может работать независимо от того, что происходит ниже. Просто разместить его случайным образом в каждой структуре - это шутка, и никогда не следует делать этого для POD.
Абсолютно согласен с вами. Но в жизни вам, вероятно, стоит поступать правильно: в школе нужно получать хорошие оценки. На вашем рабочем месте нужно выполнять требования. Если вы хотите быть упрямым, то это нормально, но объясните себя - опишите свои базы в комментариях, чтобы минимизировать ущерб, который вы можете получить.
В вашем конкретном примере выше я вижу, что вы, возможно, захотите проверить, скажем, URL. Возможно, вы даже захотите очистить заголовок и описание, но в любом случае я думаю, что это то, что вы можете сказать на ранних этапах разработки класса. Изложите свои намерения и обоснование в комментариях. Если вы не Если нужна проверка, то геттер и сеттер не нужны, вы абсолютно правы.
Простота окупается, это ценная функция. Никогда не делайте ничего религиозного.
Основная причина сделать это до того, как это понадобится, - это управление версиями.
Поля ведут себя иначе, чем свойства, особенно при использовании их в качестве lvalue (где это часто не разрешено, особенно в C #) . Кроме того, если вам понадобится позже добавить процедуры получения / установки свойств, вы сломаете ваш API - пользователям вашего класса придется переписать свой код, чтобы использовать новую версию.
Гораздо безопаснее сделать это заранее .
C # 3, кстати, упрощает эту задачу:
public class Example
{
public int MyInt { get; set; }
}
Вот хорошее длинное обсуждение этой темы: Зачем использовать геттеры и сеттеры .
Вопрос, который вы хотите задать себе: «Что произойдет через 3 месяца? с этого момента, когда вы поймете, что FeedItem.url
нуждается в проверке , но на него уже есть прямые ссылки из 287 других классов? »
Имейте в виду, что "передовые методы" кодирования часто устаревают из-за достижений в языках программирования.
Например, в C # концепция получения / установки была встроена в язык в форма собственности. C # 3.0 упростил эту задачу, введя автоматические свойства, когда компилятор автоматически генерирует для вас геттер / сеттер. В C # 3.0 также представлены инициализаторы объектов, что означает, что в большинстве случаев вам больше не нужно объявлять конструкторы, которые просто инициализируют свойства.
Итак, канонический способ C # делать то, что вы делаете, будет выглядеть так:
class FeedItem
{
public string Title { get; set; } // automatic properties
public string Description { get; set; }
public string Url { get; set; }
};
использование будет выглядеть следующим образом (с использованием инициализатора объекта):
FeedItem fi = new FeedItem() { Title = "Some Title", Description = "Some Description", Url = "Some Url" };
Дело в том, что вы должны попытаться узнать, какой лучший метод или канонический способ делать что-то является для конкретного языка, который вы используете,