Частный по сравнению с Общедоступными участниками на практике (насколько важный инкапсуляция?) [закрытый]

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

22
задан o0'. 9 May 2010 в 10:55
поделиться

22 ответа

Это зависит. Это - одна из тех проблем, которые должны быть решены практично.

предположим у меня был класс для представления точки. У меня могли быть методы get и методы set для координат X и Y, или я мог просто сделать их обоих общественностью и позволить бесплатный доступ для чтения-записи к данным. По-моему, это в порядке, потому что класс действует как прославленная структура - сбор данных с, возможно, некоторыми полезными присоединенными функциями.

Однако существует много обстоятельств, где Вы не хотите обеспечивать полный доступ к своим внутренним данным и полагаться на методы, предоставленные классом для взаимодействия с объектом. Примером был бы Запрос HTTP и ответ. В этом случае это - плохая идея позволить кому-либо отправлять что-либо по проводу - это должно быть обработано и отформатировано методами класса. В этом случае класс задуман как фактический объект и не простое хранилище данных.

Это действительно сводится, управляют ли глаголы (методы) структурой или если данные делают.

16
ответ дан Kyle Cronin 29 November 2019 в 04:37
поделиться

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

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

-1
ответ дан Matt J 29 November 2019 в 04:37
поделиться

Я следую правилам об этом почти все время. Существует четыре сценария для меня - в основном, само правило и несколько исключений (все влиявшие Java):

  1. Применимый чем-либо за пределами текущего класса, к которому получают доступ через методов get/методы set
  2. Внутреннее к классу использование, которому 'это' обычно предшествует, чтобы прояснить, что это не параметр метода
  3. , Что-то означало оставаться чрезвычайно маленьким, как транспортный объект - в основном прямой выстрел атрибутов; вся общественность
  4. Необходимый, чтобы быть нечастным за какое-то расширение
-1
ответ дан agartzke 29 November 2019 в 04:37
поделиться

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

Однако мне отчасти нравится способ Python иметь дело с ним. Членские переменные общедоступны по умолчанию. Если Вы хотите скрыть их или добавить проверку существуют методы, если, но тех считают особыми случаями.

-1
ответ дан John Mulder 29 November 2019 в 04:37
поделиться

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

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

-1
ответ дан Eclipse 29 November 2019 в 04:37
поделиться

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

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

-1
ответ дан Robert Gould 29 November 2019 в 04:37
поделиться

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

Наличие и методы считывания и методы set равно полю тому, чтобы быть общедоступным (когда методы считывания и методы set тривиальный/генерируют автоматически). Иногда могло бы быть лучше просто объявить полевую общественность, так, чтобы код был более простым, если Вам не будет нужен полиморфизм, или платформа требует, добираются/методы установки (и Вы не можете изменить платформу).

, Но существуют также случаи, где наличие методов считывания и методов set является хорошим шаблоном. Один пример:

, Когда я создаю GUI приложения, я пытаюсь сохранить поведение GUI в одном классе (FooModel) так, чтобы это могла быть единица, протестированная легко, и иметь визуализацию GUI в другом классе (FooView), который может быть протестирован только вручную. К представлению и модели присоединяются с простым кодом связующего звена; когда пользователь изменяет значение поля x, вызовы представления setX(String) на модели, которая в свою очередь может сгенерировать событие, которое изменила некоторая другая часть модели, и представление получит обновленные значения из модели с методами считывания.

В одном проекте, существует модель GUI, которая имеет 15 методов считывания и методы set, из которых только 3 добираются, методы тривиальны (таким образом, что IDE мог генерировать их). Все другие содержат некоторую функциональность или нетривиальные выражения, такие как следующее:

public boolean isEmployeeStatusEnabled() {
    return pinCodeValidation.equals(PinCodeValidation.VALID);
}

public EmployeeStatus getEmployeeStatus() {
    Employee employee;
    if (isEmployeeStatusEnabled()
            && (employee = getSelectedEmployee()) != null) {
        return employee.getStatus();
    }
    return null;
}

public void setEmployeeStatus(EmployeeStatus status) {
    getSelectedEmployee().changeStatusTo(status, getPinCode());
    fireComponentStateChanged();
}
0
ответ дан Esko Luontola 29 November 2019 в 04:37
поделиться

На практике я всегда следую только одному правилу, "никакой размер не соответствует всему" правилу.

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

-1
ответ дан Roman M 29 November 2019 в 04:37
поделиться

@VonC

Вы могли бы найти Международную организацию по Стандартизации, "Эталонная модель Открытой распределенной обработки", интересное чтение. Это определяет: "Инкапсуляция: свойство, что информация, содержавшаяся в объекте, доступна только через взаимодействия в интерфейсах, поддерживаемых объектом".

я пытался изложить доводы для того, что сокрытие информации было критической частью этого определения здесь: http://www.edmundkirwan.com/encap/s2.html

С уважением,

Ed.

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

Я утверждал бы, что этот вопрос делает путаницу понятие инкапсуляции с 'сокрытием информации'
(это не критик, так как это, действительно кажется, соответствует общей интерпретации понятия 'инкапсуляции')

Однако для меня, 'инкапсуляция' также:

  • процесс перегруппировки нескольких объектов в контейнер
  • сам контейнер, перегруппировывающий объекты

предположим, Вы разрабатываете систему налогоплательщика. Для каждого налогоплательщика Вы могли инкапсулировать понятие [1 121] ребенок в [1 115]

  • список детей, представляющих детей
  • , карта к принимает во внимание детей от различных родителей
  • объектные Дети (не Ребенок), который предоставил бы необходимую информацию (как общее количество детей)

Здесь, у Вас есть три различных видов инкапсуляций, 2 представленных контейнером низкого уровня (список или карта), один представленный объектом.

Путем принятия тех решений, Вы не делаете

  • , обнародовали ту инкапсуляцию или защищенный или частный: тот выбор 'сокрытия информации' состоит в том, чтобы все еще быть сделан
  • , делают полную абстракцию (необходимо совершенствовать атрибуты объектных Детей, и можно решить создать объектного Ребенка, который сохранил бы только соответствующую информацию с точки зрения системы налогоплательщика)
    , Абстракция является процессом выбора, какие атрибуты объекта относятся к системе, и который должен быть полностью проигнорирован.

, Таким образом, моя точка:
, Что вопрос может названный:
Частный по сравнению с Общедоступными участниками на практике (насколько важный сокрытие информации ?)

Просто мои 2 цента, все же. Я отлично уважаю тот, может рассмотреть инкапсуляцию как процесс включая решение 'сокрытия информации'.

Однако я всегда пытаюсь дифференцировать 'абстракцию' - 'инкапсуляцию' - 'сокрытие информации или видимость'.

0
ответ дан VonC 29 November 2019 в 04:37
поделиться

Соответствуйте инструменту к заданию... недавно, я видел некоторый код как это в моей текущей кодовой базе:

private static class SomeSmallDataStructure {
    public int someField;
    public String someOtherField;
}

И затем этот класс использовался внутренне для того, чтобы легко раздать несколько значений данных. Это не всегда имеет смысл, но если у Вас есть просто ДАННЫЕ без методов, и Вы не представляете его клиентам, я нахожу его довольно полезным шаблоном.

новое использование я имел этого, была страница JSP, где у меня была таблица данных, отображаемых, определенных наверху декларативно. Так, первоначально это было в нескольких массивах, одном массиве на поле данных..., которое это закончило в коде, являющемся довольно трудным пробраться через с полями, не являющимися друг рядом с другом в определении, которое будет отображено вместе..., таким образом, я создал простой класс как вышеупомянутый, который сплотит его..., результатом был ДЕЙСТВИТЕЛЬНО читаемый код, намного больше, чем прежде.

Мораль... иногда необходимо считать "принятым плохо" альтернативы, если они могут сделать код более простым и легким для чтения, пока Вы продумываете его и полагаете, что последствия... вслепую не принимают ВСЕ, что Вы слышите.

, Который сказал..., общедоступные методы get и методы set в значительной степени эквивалентны общедоступным полям..., по крайней мере, по существу (существует немного больше гибкости, но это - все еще плохой шаблон для применения к КАЖДОМУ полю, которое Вы имеете).

Даже библиотеки стандарта Java имеет некоторые случаи общедоступные поля .

0
ответ дан Mike Stone 29 November 2019 в 04:37
поделиться

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

, Например: Человек. Рука. Захват (howquick, howmuch);

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

0
ответ дан Al. 29 November 2019 в 04:37
поделиться

Моя тенденция состоит в том, чтобы попытаться сделать все частным, если это возможно. Это сохраняет границы объекта максимально ясно определенными и сохраняет объекты максимально разъединенными. Мне нравится это потому что, когда я должен переписать объект, что я испортил первое (второй, пятый?) время, это сохраняет повреждение содержавшим к меньшему числу объектов.

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

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

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

0
ответ дан Jonathan Adelson 29 November 2019 в 04:37
поделиться

Инкапсуляция важна когда по крайней мере одно из этих хранений:

  1. Любой, но Вы собирается использовать Ваш класс (или они повредят Ваши инварианты, потому что они не читают документацию).
  2. Любой, кто не читает документацию, собирается использовать Ваш класс (или они повредят Ваши тщательно задокументированные инварианты). Обратите внимание, что эта категория включает you-two-years-from-now.
  3. В какой-то момент в будущем кто-то собирается наследоваться Вашему классу (потому что, возможно, дополнительные меры должны быть приняты, когда значение поля изменяется, таким образом, должен быть метод set).

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

0
ответ дан Thomas 29 November 2019 в 04:37
поделиться

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

кроме того, theorectically можно изменить конкретную реализацию или что-то, но так как по большей части это:

private Foo foo;
public Foo getFoo() {}
public void setFoo(Foo foo) {}

немного трудно выровнять по ширине.

0
ответ дан SCdF 29 November 2019 в 04:37
поделиться

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

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

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

<час>

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

1
ответ дан Noel Walters 29 November 2019 в 04:37
поделиться

Свойства C# 'моделируют' общедоступные поля. Выглядит довольно прохладным, и синтаксис действительно ускоряет создание, те добираются/методы установки

1
ответ дан Richard Walton 29 November 2019 в 04:37
поделиться

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

Пример: я пишу код, который обновляет переменную, и я должен сделать абсолютно уверенным, что Gui изменяется для отражения изменения, самый легкий путь состоит в том, чтобы добавить метод доступа (иначе "Метод set"), вместо которого называют того, чтобы обновить данные, обновляется.

, Если я обнародовал те данные, и что-то заменяет переменную, не проходя Метод установщика (и это происходит каждый раз ругательства), тогда кто-то должен будет провести час, отлаживая для обнаружения, почему обновления не отображаются. То же применяется, до меньшей степени, до "Получения" данных. Я мог поместить комментарий в заголовочный файл, но разногласия - то, что никто не считает его, пока что-то не пойдет ужасно, ужасно неправильно. Осуществление его с частным означает, что ошибка не может быть сделанной, потому что это обнаружится как легко расположенная ошибка времени компиляции, а не ошибка во время выполнения.

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

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

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

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

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

2
ответ дан 2 revs, 2 users 97% 29 November 2019 в 04:37
поделиться

Я склонен следовать правилу довольно строго, даже когда это - просто мой собственный код. Мне действительно нравятся Свойства в C# по этой причине. Это делает действительно легким управлять тем, что оценивает, это дано, но можно все еще использовать их в качестве переменных. Или сделайте набор частным и получить общественность, и т.д.

2
ответ дан Joel 29 November 2019 в 04:37
поделиться

Я предпочитаю сохранять участников частными максимально долго и только получать доступ к ним через методов get, даже из того же самого класса. Я также стараюсь избегать методов set как первого проекта для продвижения объектов стиля значения, пока это возможно. При работе с внедрением зависимости много, у Вас часто есть методы set, но никакие методы get, поскольку клиенты должны быть в состоянии настроить объект, но (других) не, не узнают то, что acutally настроено, поскольку это - деталь реализации.

С уважением, Ollie

3
ответ дан Oliver Drotbohm 29 November 2019 в 04:37
поделиться

Да, вопросы инкапсуляции. Представление конкретной реализации делает (по крайней мере) две вещи неправильно:

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

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

8
ответ дан Derek Park 29 November 2019 в 04:37
поделиться

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

16
ответ дан Smashery 29 November 2019 в 04:37
поделиться
Другие вопросы по тегам:

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