Полезна ли неизменность в непараллельных приложениях? - PullRequest
8 голосов
/ 23 июня 2009

Мне нравится концепция неизменяемости, но иногда мне интересно, когда приложение не должно быть параллельным, следует ли избегать превращения вещей в неизменяемые?

Когда приложение не является многопоточным, вас не беспокоят проблемы общего состояния, верно?

Или неизменность - это такая концепция, как ООП, которую вы используете полностью или нет? Исключая случаи, когда что-то не должно быть неизменным в зависимости от использования / производительности и т. Д.

Я сталкивался с этим вопросом при написании приложения для себя, которое достаточно велико (может быть, как 1-2 тыс. Строк).

Ответы [ 3 ]

9 голосов
/ 23 июня 2009

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

8 голосов
/ 23 июня 2009

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

Когда вы передаете объект другому компоненту, например List<T>, вы зависите от того, что делает этот компонент. Это особенно важно, когда вы возвращаете коллекции как свойства.

public class Foo { 
  private List<Bar> _barList;
  public ICollection<Bar> BarList { get return _barList; } 
}

Ничто не мешает потребителю этого класса убрать коллекцию из-под меня. Даже переключение типа возврата на IEnumerable<Bar> не совсем безопасно. Ничто не останавливает какой-то кусок плохо написанного кода, приведя его обратно к List<T> и вызвав .Clear ().

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

public class Foo {
  private ImmutableCollection<Bar> _barList;
  public ImmutableCollection<Bar> BarList { get { return _barList; } }
}

Теперь я не могу доверять другому коду от неправильного использования моего класса. Они не могут испортить это.

2 голосов
/ 30 сентября 2012

Основным преимуществом неизменяемости является то, что не нужно отслеживать владение неизменяемыми объектами. Они просто существуют до тех пор, пока они кому-нибудь нужны, а затем исчезают в ничто, когда они больше не нужны. Хотя использование сборщика мусора во многих случаях означает, что нет необходимости писать какой-либо код, прямо связанный с владением изменяемыми объектами (за исключением тех, которые реализуют IDisposable), во многих случаях очень сложно написать правильный код, в котором объекты которые имеют изменяемое состояние, не имеют одного четко определенного «владельца». Путаница в том, кому принадлежит состояние изменчивых объектов, может быть очень частым источником ошибок; при использовании неизменяемых объектов (кроме нескольких, которые реализуют IDisposable), обычно можно игнорировать проблемы владения.

Другой момент, который следует учитывать, заключается в том, что гораздо проще рассуждать об изменчивой ссылке на семантически неизменяемый объект или неизменяемой ссылке на изменяемый объект, чем об изменчивой ссылке на изменяемый объект. Если есть изменяемая ссылка на изменяемые объекты, часто может быть неясно, является ли правильный подход к обновлению состояния простым изменением объекта напрямую или копированием его состояния в новый объект, изменением этого и обновлением ссылки. В некоторых случаях могут возникать обстоятельства, требующие каждого типа операции (например, List<T>, который иногда заменяет массив на больший, но обычно выполняет обновления на месте), но такой подход работает только в том случае, если тип поддерживает исключительный тип. контроль над изменяемыми объектами. Часто более полезно либо иметь неизменяемую ссылку на изменяемый тип (в этом случае код может предоставлять ссылку, возможно, через оболочку только для чтения, другим объектам, которые хотят получить «живое представление» своего состояния), либо иметь изменяемая ссылка на объект, который является неизменным или, как минимум, никогда не будет видоизменяться во время существования ссылки.

...