Основным преимуществом глубоко неизменяемых объектов является то, что очень просто сделать «снимок» их свойств - просто скопируйте ссылку на объект. Независимо от того, насколько большим или сложным может быть объект, можно «сделать снимок» всего этого, просто скопировав одну ссылку.
Напротив, если кто-то хочет сделать снимок свойств изменяемого объекта, необходимо скопировать все из них. Если какое-либо из этих свойств само по себе является изменяемым объектом, необходимо будет также скопировать все эти свойства. В некоторых случаях создание полезной копии состояния изменяемого объекта может быть очень сложным или даже невозможным, поскольку их состояние может быть переплетено с состоянием синглетонов.
Хотя неизменяемые объекты гораздо проще «снимать», чем изменяемые, иногда, учитывая неизменяемый объект, иногда бывает трудно создать экземпляр, который похож на первый, за исключением некоторых незначительных изменений. В этом отношении с изменяемыми объектами иногда легче работать. Иногда может быть полезно скопировать данные из неизменяемого объекта в изменяемый объект, изменить его, а затем создать новый неизменяемый объект, который содержит измененные данные. К сожалению, нет никаких общих способов автоматизировать такое преобразование с помощью классов. Однако есть альтернатива.
Структура с открытыми полями, которые являются примитивами значений или ссылками на неизменяемые классы, может предложить очень удобный способ хранения информации в неизменяемом объекте, копирования ее в изменяемую форму, изменения ее и создания нового неизменяемого объекта. Альтернативно, можно легко скопировать данные в структуру, просто скопировав саму структуру. Копирование структуры, содержащей более одного или двух полей размером int
, несколько дороже, чем копирование ссылки на неизменяемый объект, но копирование структуры и ее изменение, как правило, намного дешевле, чем создание нового измененного неизменяемого объекта. Важно отметить, что из-за некоторых странностей в том, как языки .net обрабатывают структуры, некоторые люди считают изменяемые структуры злом. Я бы порекомендовал, что в общем случае для структур лучше всего просто выставлять свои поля и избегать использования каких-либо методов (кроме конструкторов), которые изменяют this
. Это позволит избежать большинства причуд, связанных с изменяемыми структурами, и будет часто предлагать лучшую производительность и более четкую семантику, чем это можно получить с неизменяемыми классами, изменяемыми классами или так называемыми неизменяемыми (действительно «изменяемыми только при присваивании») структурами. *
Между прочим, иногда полезно спроектировать неизменный объект, чтобы при создании немного отличающегося объекта все объекты из старого объекта копировались в новый, но с изменением соответствующей части, а иногда полезно создать неизменный объект. объект, так что немного другой объект сможет «повторно использовать» большую часть исходного объекта. Во многих случаях первый подход будет более эффективным, если объект будет читаться гораздо чаще, чем пишется, и не будет необходимости хранить старые снимки после того, как объект был изменен. Последний подход может быть более эффективным в тех случаях, когда требуется хранить много снимков, а обновления происходят часто относительно доступа к чтению.