Оборотные стороны к неизменным объектам в Java? [закрытый]

12 ответов

Но каковы недостатки предпочитаете неизменные объекты в Java? несовместимость с ORM или веб инструменты представления?

Основанные на отражении фреймворки усложняются неизменяемыми объектами, поскольку они требуют внедрения конструктора :

  • в Java нет аргументов по умолчанию, что вынуждает нас ВСЕГДА предоставлять все необходимые зависимости
  • ] переопределение конструктора может быть грязным
  • имена аргументов конструктора обычно не доступны через отражение, что заставляет нас зависеть от порядка аргументов для разрешения зависимостей

Сложности реализации?

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

Можно ли спроектировать крупномасштабную систему (граф глубоких объектов), которая преимущественно использует неизменяемые объекты?

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

19
ответ дан 27 November 2019 в 21:00
поделиться

Моя самая большая проблема с неизменяемыми структурами данных - как их сохранить / восстановить. То есть, если у класса есть последние поля, я не могу его создать, и затем установить его поля.

-1
ответ дан 27 November 2019 в 21:00
поделиться

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

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

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

0
ответ дан 27 November 2019 в 21:00
поделиться

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

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

0
ответ дан 27 November 2019 в 21:00
поделиться

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

class Mutable {
    State1 f1;
    MoreState f2;
    void doSomething() {  // mutate the state, but don't document it }
    void doSomethingElse()  /// mutate the state heavily, do not mention in doc
}  

(Обратите внимание на отсутствующий интерфейс Cloneable).

В настоящее время проблема с сборщиком мусора не такая большая. ВМ довольны недолговечными объектами.

Достижения в технологии компиляции / JIT позволят рано или поздно оптимизировать создание промежуточных временных объектов. Например:

BigInteger  three =, two =, i1 = ...;
BigInteger  i2 = i1.mul(three).div(two);  

JIT может заметить, что промежуточный объект i1.mul (три) может быть использован для конечного результата, и вызвать вариант метода div, который работает с изменяемым аккумулятором.

1
ответ дан 27 November 2019 в 21:00
поделиться

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

1
ответ дан 27 November 2019 в 21:00
поделиться

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

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

1
ответ дан 27 November 2019 в 21:00
поделиться

Вы в значительной степени ответили на свой вопрос. Я не верю, что в спецификации JavaBean упоминается что-либо об неизменяемости, но JavaBeans - это «хлеб с маслом» многих фреймворков Java.

2
ответ дан 27 November 2019 в 21:00
поделиться

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

Если вы действительно посмотрите на программы, использующие изменяемые объекты, вы обнаружите, что они склонны «атаковать», изменяя:

  • объекты, передаваемые в конструкторы
  • объекты, передаваемые в методы
  • объекты, возвращаемые из методов.

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

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

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

3
ответ дан 27 November 2019 в 21:00
поделиться

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

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

15
ответ дан 27 November 2019 в 21:00
поделиться

в неизменяемых данных вы не устанавливаете вещи дважды ... см. Haskell и scala vals (и закрытие курса) ...

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

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

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

0
ответ дан 27 November 2019 в 21:00
поделиться

См. Функциональная Java , чтобы получить исчерпывающий ответ на ваш вопрос.

1
ответ дан 27 November 2019 в 21:00
поделиться
Другие вопросы по тегам:

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