Полезна ли неизменность в непараллельных приложениях?

StackOverflow https://stackoverflow.com/questions/1029611

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

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

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

Еще один момент, который следует учитывать, заключается в том, что гораздо проще рассуждать об изменчивой ссылке на семантически неизменяемый объект или неизменной ссылке на изменяемый объект, чем об изменчивой ссылке на изменяемый объект. Если есть изменяемая ссылка на изменяемые объекты, часто может быть неясно, является ли правильный подход к обновлению состояния простым изменением объекта напрямую или копированием его состояния в новый объект, изменением этого и обновлением ссылки. В некоторых случаях могут возникать обстоятельства, требующие каждого типа операции (например, <=>, который иногда заменяет массив на больший, но обычно выполняет обновления на месте), но такой подход работает только в том случае, если тип поддерживает монопольный режим. контроль над изменяемыми объектами. Часто более полезно иметь неизменную ссылку на изменяемый тип (в этом случае код может предоставить ссылку, возможно, через оболочку только для чтения, другим объектам, которые хотят & Quot; live view & Quot; его состояния) или же иметь изменяемую ссылку на объект, который является неизменным или, по крайней мере, никогда не будет видоизменяться в течение жизни ссылки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top