Нет ли точка, где инкапсуляция становится смешной?

Я использую следующие два плагина все время:

  • проект
  • vimoutliner
11
задан Tarnay Kálmán 11 November 2009 в 02:17
поделиться

12 ответов

Это вопрос "передовой практики" и стиля.

  • Вы никогда не захотите раскрывать свои данные напрямую. Вы всегда хотите иметь возможность контролировать доступ к ним. Я согласен, в данном случае это кажется немного смешным, но он предназначен для того, чтобы научить вас этому стилю, чтобы вы к нему привыкли.
  • Это помогает определить последовательный интерфейс для классов. Вы всегда знаете, как к чему-то добраться -> вызвать метод get.

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

14
ответ дан 3 December 2019 в 00:54
поделиться

Геттеры / сеттеры, конечно, являются хорошей практикой, но их утомительно писать и, что еще хуже, читать.

Сколько раз мы читали класс с полдюжиной членов переменные и сопутствующие геттеры / сеттеры, каждый из которых имеет полный код hog @ param / @ return HTML, известный бесполезный комментарий вроде «получить значение X», «установить значение X», «получить значение Y», «установить значение Y ',' получить значение Z ',' установить значение Zzzzzzzzzzzzz. бац!

1
ответ дан 3 December 2019 в 00:54
поделиться

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

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

Инкапсуляция теоретически полезна в случае, если внутренняя реализация когда-либо изменится. Например, если URL-адрес для каждого объекта стал вычисленным результатом, а не сохраненным значением, то инкапсуляция getUrl () продолжила бы работать. Но я подозреваю, что вы уже слышали об этом.

0
ответ дан 3 December 2019 в 00:54
поделиться

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

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

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

Простые классы, которые вы создаете в классе, неадекватно иллюстрируют необходимость четко определенного интерфейса. Говоря "Но почему бы и нет?"

1
ответ дан 3 December 2019 в 00:54
поделиться

Как разработчик C ++ я делаю своих участников всегда закрытыми, просто чтобы быть последовательным. Так что я всегда знаю, что мне нужно набирать px (), а не px

Кроме того, я обычно избегаю реализации методов установки. Вместо изменения объекта я создаю новый:

p = Point(p.x(), p.y() + 1);

Это также сохраняет инкапсуляцию.

1
ответ дан 3 December 2019 в 00:54
поделиться

В какой-то момент инкапсуляция становится нелепой.

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

Каждый, кто знает C, может отладить ужасно написанную функцию из 1000 строк, которая использует только стандартную библиотеку базового языка C. . Не каждый может отлаживать придуманный вами фреймворк. Каждая введенная инкапсуляция / абстракция уровня должна быть сопоставлена ​​со стоимостью. Это не значит, что оно того не стоит, но, как всегда, вы должны найти оптимальный баланс для вашей ситуации.

1
ответ дан 3 December 2019 в 00:54
поделиться

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

См. http://www.pragprog.com/articles/tell-dont-ask

Теперь давайте представим, что ваш класс FeedItem имеет стали невероятно популярными и используются проектами повсеместно. Вы решаете, что вам нужно (как предлагали другие ответы) проверить предоставленный URL.

Счастливые дни, вы написали установщик для URL. Вы редактируете его, проверяете URL-адрес и генерируете исключение, если оно недействительно. Вы выпускаете новую версию класса, и все, кто ее использует, довольны. (Давайте проигнорируем отмеченные и непроверенные исключения, чтобы не сбиться с пути.)

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

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

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

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

3
ответ дан 3 December 2019 в 00:54
поделиться

Если что-то представляет собой простую структуру, тогда да, это смешно, потому что это просто ДАННЫЕ.

На самом деле это просто возврат к началу ООП, где люди до сих пор не поняли идеи классов вообще. Нет причин иметь сотни методов get и set на случай, если вы когда-нибудь измените getId () на удаленный вызов телескопа Хаббла.

Вам действительно нужна эта функциональность на ВЕРХНЕМ уровне, внизу она бесполезна . IE, у вас будет сложный метод, которому для работы был отправлен чистый виртуальный класс, гарантирующий, что он все еще может работать независимо от того, что происходит ниже. Просто разместить его случайным образом в каждой структуре - это шутка, и никогда не следует делать этого для POD.

4
ответ дан 3 December 2019 в 00:54
поделиться

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

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

Простота окупается, это ценная функция. Никогда не делайте ничего религиозного.

4
ответ дан 3 December 2019 в 00:54
поделиться

Основная причина сделать это до того, как это понадобится, - это управление версиями.

Поля ведут себя иначе, чем свойства, особенно при использовании их в качестве lvalue (где это часто не разрешено, особенно в C #) . Кроме того, если вам понадобится позже добавить процедуры получения / установки свойств, вы сломаете ваш API - пользователям вашего класса придется переписать свой код, чтобы использовать новую версию.

Гораздо безопаснее сделать это заранее .

C # 3, кстати, упрощает эту задачу:

public class Example
{
    public int MyInt { get; set; }
}
7
ответ дан 3 December 2019 в 00:54
поделиться

Вот хорошее длинное обсуждение этой темы: Зачем использовать геттеры и сеттеры .

Вопрос, который вы хотите задать себе: «Что произойдет через 3 месяца? с этого момента, когда вы поймете, что FeedItem.url нуждается в проверке , но на него уже есть прямые ссылки из 287 других классов? »

13
ответ дан 3 December 2019 в 00:54
поделиться

Имейте в виду, что "передовые методы" кодирования часто устаревают из-за достижений в языках программирования.

Например, в 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" };

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

3
ответ дан 3 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

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