Immutable object
Immutable object (česky neměnný objekt) je název pro návrhový vzor, používaný při programování. Vyznačuje se tím, že žádná z jeho metod není schopná změnit jeho nastavenou hodnotu.
Účel
Vzor se hodí pro případy, kdy nechceme, aby se nám mohla změnit hodnota objektu, se kterým pracujeme. Změnit hodnotu mutable objektů (tj. opak immutable objektů) nám při běhu programu může např. jiné vlákno.
Matematický náhled na proměnné
Z pohledu matematiky se spíše než o proměnných mluví o tzv. neznámých: Možná již mají nějakou hodnotu, možná ji teprve získají, až ji určíme či nalezneme výpočtem, pak už se však nebude měnit.
Prakticky tedy jde o zápis do RAM, ne o fixní ROM, ani o konstantu, jakmile se však tato hodnota jednou zapíše, přepsání již není možné.
Takovému přístupu odpovídají "proměnné" v XSLT: Pro každý běh sice mají jinou hodnotu, ale během jednoho běhu je lze nastavit jen jednou. Jakmile se jejich hodnota změní z null na nějakou konkrétní, typicky předáním hodnoty již při zavolání šablony, již tuto hodnotu nelze měnit. Sporné tedy je i založení nějaké nové (například pomocné) "proměnné" někde během zpracování, později, než při inicializaci pro spuštění.
Základní implementace
Implementace vzoru se skládá z vytvoření jednoho (či více) privátních atributů, ve kterých uložíme hodnotu. Dále musíme zajistit nastavení těchto atributů. Nejčastěji se hodnota nastaví již při tvorbě objektu – tedy v konstruktoru.
Další možností je mít setter, ve kterém hodnotu nastavíme. Ovšem v tomto případě musíme zajistit, že pokud se o nastavení hodnoty pokusí někdo další (tedy změnit hodnotu objektu), tak se operace nepovede (například vyvoláme výjimku).
Implementace v jazyce PHP
V ukázce vidíme, že přestože posouváme bod v rovině o určitý vektor, tak vracíme nový bod. Tím zajistíme, že jsme nezměnili hodnoty původního objektu.
class Point
{
private $x;
private $y;
public function __construct($x, $y)
{
$this->x = $x;
$this->y = $y;
}
public function getX()
{
return $this->x;
}
public function getY()
{
return $this->y;
}
/**
* Posune bod o dany vektor
*
* Predpokladame rozhrani tridy vektor:
* $vector->getX();
* $vector->getY();
*/
public function addVector(Vector $vector)
{
$x = $this->x + $vector->getX();
$y = $this->y + $vector->getY();
return new Point($x, $y);
}
public function __toString()
{
return "[" . $this->x . ", " . $this->y . "]";
}
}
$point1 = new Point(0, 0);
$point2 = $point1->addVector(new Vector(1, 2));
// $point1 a $point2 jsou ruzne objekty
$dumpPoint1 = (string)$point1; // [0, 0]
$dumpPoint2 = (string)$point2; // [1, 2]
Odkazy
Literatura
- PECINOVSKÝ, Rudolf. Návrhové vzory – 33 vzorových postupů pro objektové programování. Brno: Computer Press, 2007. ISBN 978-80-251-1582-4.
Související články
- lazy initialization, odložená inicializace
- objektově orientované programování