При рассмотрении объектной инкапсуляции методы считывания должны возвратить неизменное свойство?

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

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

18
задан Durandal 22 February 2014 в 21:48
поделиться

11 ответов

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

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

6
ответ дан 30 November 2019 в 08:16
поделиться

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

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

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

6
ответ дан 30 November 2019 в 08:16
поделиться

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

5
ответ дан 30 November 2019 в 08:16
поделиться

В особом случае Набора, Списка, Набора или Карты в Java, легко возвратить неизменное представление классу с помощью return Collections.unmodifiableList(list);

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

3
ответ дан 30 November 2019 в 08:16
поделиться

Joshua Bloch в его превосходном "Эффективном Java" книга говорит, что необходимо ВСЕГДА делать защитные копии при возврате чего-то вроде этого. Это может быть небольшим экстремальным значением, особенно если объектами ContactDetails не является Cloneable, но это всегда - безопасный путь. Если в сомнении всегда способствуют безопасности кода по производительности - если профилирование не показало, что cloneing является реальным узким местом производительности.

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

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

3
ответ дан 30 November 2019 в 08:16
поделиться

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

2
ответ дан 30 November 2019 в 08:16
поделиться

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

1
ответ дан 30 November 2019 в 08:16
поделиться

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

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

Документация является, вероятно, самым прагматическим решением ;)

1
ответ дан 30 November 2019 в 08:16
поделиться

Ваш первый императив должен быть должен следовать Закону Demeter, или ‘Tell не делают ask’; скажите экземпляр объекта, что сделать, например,

contact.print( printer ) ;  // or
contact.show( new Dialog() ) ; // or
contactList.findByName( searchName ).print( printer ) ;

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

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

1
ответ дан 30 November 2019 в 08:16
поделиться

Когда я начинал, я все еще в большой степени находился под влиянием, СКРЫВАЮТ ВАШИ ДАННЫЕ ПРИНЦИПАЛЫ OO LOL. Я сидел бы и обдумал бы то, что произошло бы, если бы кто-то изменил состояние одного из объектов, выставленных свойством. Я должен сделать их только для чтения для внешних вызывающих абонентов? Разве я не должен выставлять их вообще?

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

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

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

0
ответ дан 30 November 2019 в 08:16
поделиться

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

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

Что касается создания самих неизменных объектов, необходимо фактически всегда делать участников в объектном финале, если у Вас нет веской причины не к (Финал должен был быть значением по умолчанию, "изменяемый" должно быть ключевое слово, которое переопределяет то значение по умолчанию). Это подразумевает, что по мере возможности, объекты будут неизменны.

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

0
ответ дан 30 November 2019 в 08:16
поделиться
Другие вопросы по тегам:

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