Изменяемый по сравнению с неизменными объектами

165
задан Machavity 2 November 2018 в 12:32
поделиться

4 ответа

Ну, существует пара аспектов к этому. Номер один, изменяемые объекты без ссылочных идентификационных данных могут вызвать ошибки в нечетные времена. Например, рассмотрите Person боб с основанным на значении equals метод:

Map<Person, String> map = ...
Person p = new Person();
map.put(p, "Hey, there!");

p.setName("Daniel");
map.get(p);       // => null

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

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

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

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

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

157
ответ дан Daniel Spiewak 23 November 2019 в 21:10
поделиться

Неизменные объекты являются очень мощным понятием. Они устраняют большую нагрузку попытки сохранить объекты/переменные последовательными для всех клиентов.

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

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

Самое Большое преимущество: неизменность + объектная семантика + интеллектуальные указатели делают монопольное использование объекта надуманным вопросом, всеми клиентами, объект имеет их собственную частную копию по умолчанию. Неявно это также означает детерминированное поведение в присутствии параллелизма.

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

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

10
ответ дан Igor Patsian 23 November 2019 в 21:10
поделиться

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

6
ответ дан John Millikin 23 November 2019 в 21:10
поделиться

Изменяемый объект является просто объектом, который может быть изменен после того, как он создается/инстанцируется, по сравнению с неизменным объектом, который не может быть изменен (см. страница Wikipedia на предмете). Примером этого на языке программирования являются списки Python и кортежи. Списки могут быть изменены (например, новые объекты могут быть добавлены после того, как это создается), тогда как кортежи не могут.

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

4
ответ дан willurd 23 November 2019 в 21:10
поделиться
Другие вопросы по тегам:

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