Неизменим обект

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене

В обектно ориентираното програмиране и функционалното програмиране неизменим обект е обект, чието състояние не може да се промени веднъж след като е бил създаден. Един обект може да бъде и частично неизменим ако само някои от полетата (атрибутите) му са неизменими. За неизменим може да се счита и обект който променя само някои свои „вътрешни“ полета (например декларирани като private), и те не влияят на функционалността на обекта.

Обекти които могат да бъдат променяни пък се наричат изменими.

Употреба[редактиране | edit source]

Основания за употребата на неизменими обекти са увеличената скорост на изпълнение на някои операции върху тях и по-голямата сигурност при употребата им. За да се направи копие на неизменим обект, например, е необходимо да се копира единствено самата референция (или указател) към него, спестявайки времеемкото копиране на целия обект както и паметта необходима за него. Въпреки че това може да се реализира и с изменими обекти, неизменчивостта гарантира че обектът няма да бъде променян чрез едната референция и това да се отрази на употребата на другата референция, което би могло да доведе до труднооткриваеми грешки. В допълнение, при този начин на копиране, проверката за еднаквост на обектите също може да се се ускори значително — достатъчно е да се сравнят самите референции към обектите, а не всички полета на самите обекти. Това е възможно само при допълнителното условие, че се проверява (от програмиста или програмното осигуряване) преди създаването на нов обект, дали вече не съществува идентичен такъв и ако това е така — да се създаде само референция към вече съществуващия обект.

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

Подобни свойства могат да придобият и изменимите обекти при използването на техниката копиране при запис (copy on write). В този случай, копия на обектите отново се създават чрез копиране на референцията към тях, но ако чрез някоя от референциите този обект се промени, се създава съответния нов обект. Така, докато не бъдат изменени, тези обекти споделят предимствата на неизменимите обекти.

Java[редактиране | edit source]

В Java, символните низове са неизменими. Затова е невъзможно те да бъдат индексирани и променяни на място както в C да речем. Да вземем следния пример:

String s = "ABC";
s = s.toLowerCase();

Методът toLowerCase(), не променя обекта сочен от s, а връща друг (също неизменим) обект, който представлява трансформация на предишния. Стъпка по стъпка, в горния пример се случва следното:

  1. Създава се обект от тип String отговарящ на низа "ABC".
  2. Референция към този обект се записва в променливата s.
  3. Създава се нов обект от тип String съответстващ на низа 'abc'.
  4. Референция към последния обект се записва в променливата s.

След това, ако към първоначалния обект съответстващ на "ABC" няма други референции, той ще бъде унищожен от сметосъбирача (garbage collector).

Реализация[редактиране | edit source]

Някои програмни езици имат вградени прости неизменими типове данни. За да бъде един клас дефиниран от потребителя неизменим обаче, е необходимо самият потребител да се погрижи това да е така. Това обикновено се реализира като не се допуска никой метод да променя състоянието на обекта и всички негови полета бъдат декларирани като константи (const). Много пъти обаче това не е достатъчно и съществуват езикови средства които биха могли да заобиколят „барикадите“ поставени около обекта и да извършат промяна. Въпреки това и в тези случаи може да се говори за неизменим обект, тъй като е невъзможна неволната промяна на обекта, което обикновено е достатъчно.

Java[редактиране | edit source]

В Java, обекти от вграденият клас String са неизменими. За да създава неизменими обекти, един потребителски клас може да се дефинира по следния начин:

class Student {
    private final String name;
 
    public Cart(String name) { this.name = name; }
    public getName() { return new String(name); }
}

Така референцията name не може да бъде променяна, защото е декларирана final. Обектът сочен от name е неизменим защото е от клас String. Името на студента се инициализира с конструктора Cart() и може да се поиска с getName() без да се променя състоянието на обекта.

Python[редактиране | edit source]

Python има няколко вградени неизменими типа.

Scala[редактиране | edit source]

В Scala, всяка променлива може да бъде декларирана като неизменима чрез ключовата дума var:

val maxValue = 100
var currentValue = 1

maxValue е неизменим, докато currentValue е изменим.