Változhatatlan objektum

Egy megváltoztathatatlan objektumot , az objektum orientált és funkcionális programozás , egy tárgy , amelynek állapotát nem lehet megváltoztatni a létrehozása után. Ezt a koncepciót szembe kell állítani a változó objektuméval .

Tábornok

Mielőtt a megjelenése objektum-orientált programozás , futásidejű változók, amelyek tartalma nem volt célja a változás futás közben (például a konverziós tényező, hogy átalakítsa font a kilogramm , vagy az értéke pi több tizedesjegyig) néven váltak ismertté állandók , hogy különbséget azoktól, amelyeken változtatni lehet.

Az objektumorientált nyelvek többségében az objektumokat hivatkozások manipulálják . Ez a helyzet például a Java , típusú objektumok classa C # és Swift (ellentétben típusú objektumok struct) a Python a JavaScript és a Ruby . Ebben az esetben fontos, hogy a megosztott objektum állapota hivatkozással megváltoztatható-e vagy sem.

Ha egy objektum megváltoztathatatlannak tekinthető, akkor a teljes objektum másolása helyett másolat nyerhető a referencia egyszerű lemásolásával. Mivel egy referencia (amely általában csak a memóriában levő mutató méretét foglalja el ) általában jóval kisebb, mint maga az objektum, ez a technika memóriát takarít meg, és javítja a végrehajtás sebességét.

A referenciák másolásának technikája sokkal összetettebb a változó objektumoknál, mert ha egy változó objektumra való hivatkozást használó elem módosítja az utóbbit, akkor a módosítás a referenciát használó összes többi elem számára láthatóvá válik. Abban az esetben, ha ez nem a kívánt hatás, nehéz lehet elérni, hogy más felhasználók helyesen reagáljanak. Ilyen helyzetben az objektum egészének megelőző másolása gyakran használt megoldás, de drága. A megfigyelő tervezési mintája alternatív megoldást jelent a változó objektumok változásainak kezelésére.

A megváltoztathatatlan objektumok felhasználhatók többszálas alkalmazásokban . Több szál változatlan objektumként megvalósított adatokat használhat, anélkül, hogy aggódnia kellene egy párhuzamos szál esetleges módosítása miatt. Éppen ezért a változhatatlan objektumokat biztonságosabbnak tekintik egy többszálas környezetben, mint a változó objektumokat.

A technikát, amely abban áll, hogy az azonos változhatatlan objektumok másolatai helyett mindig hivatkozásokat használunk, értéküket csak egyszer tároljuk a memóriában, angolul "internálásnak" nevezzük. Ebben az összefüggésben két objektum akkor és akkor tekinthető egyenlőnek, ha hivatkozásuk, amelyet általában egész számok képviselnek, egyenlőek. Néhány nyelv automatikusan kezeli ezt a technikát: például a Python automatikusan kezeli a rövid húrokat. Ha az internálást megvalósító algoritmus garantálja ennek megvalósítását, amikor csak lehetséges, akkor a két objektum közötti egyenlőség összehasonlítása a mutatók összehasonlítására redukálódik, ami jelentős sebességnövekedést jelent a folyamatban. Az internálás általában csak a megváltoztathatatlan tárgyakat érdekli.

Előfordulhat, hogy egy objektumnak csak bizonyos mezői változtathatatlanok: maga az objektum csak akkor változhatatlan, ha az összes mezője megváltoztathatatlan. Ez lehetővé teheti például egy objektum bizonyos adatainak arra kényszerítését, hogy változatlanok maradjanak az objektum teljes élettartama alatt. Bizonyos nyelvekben ezt egy kulcsszóval lehet elérni (például consta C ++ vagy finala Java nyelven ). Más nyelveken ez fordítva történik: az OCaml- ben az objektum mezői alapértelmezés szerint megváltoztathatatlanok , és adott esetben kifejezetten változóként kell megjelölni őket.

Programozási nyelvekben

A megváltoztathatatlanság nem jelenti azt, hogy az objektum, mivel a memóriában van tárolva, nem írható át. Inkább egy fordítási irányelv, amely jelzi, hogy a programozónak mit szabad megengednie az objektum normál felületén keresztül, és nem azt, hogy mit lehet abszolút értelemben megtenni (például a gépelési rendszer megkerülése vagy consta C vagy C ++ nyelven történő kezelés szabályainak megsértése esetén ).

C ++

VS #

Itt van egy példa a C # változhatatlan objektumára:

class Position2D { private readonly double _x; private readonly double _y; public double X { get { return _x; }} public double Y { get { return _y; }} public Position2D(double x, double y) { _x = x; _y = y; } }

Jáva

A Java megváltoztathatatlan objektumának klasszikus példája az osztály példányosítása String :

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

A módszer toLowerCase()nem módosítja a karakterláncban szereplő "ABC" értéket s. Ehelyett egy új String objektumot példányosítanak, és annak összeállításakor az "abc" értéket kapják. A metódus toLowerCase()visszaadja a String objektum hivatkozását. Ha azt szeretné, hogy a karakterlánc startalmazza az "abc" értéket, akkor más megközelítést kell használnia:

s = s.toLowerCase();

Ebben az esetben a karakterlánc segy új String objektumra hivatkozik, amely "abc" -t tartalmaz. A String osztály objektumának deklarációjában semmi nem korlátozza megváltoztathatatlanságra: sokkal inkább az, hogy a String osztályhoz társított módszerek egyike sem befolyásolja az ilyen objektum értékét, ami tényleges változatlanná teszi.

Itt van most egy példa egy Java objektumra, amely a változhatatlanság különböző definícióitól függően változóként vagy megváltoztathatatlannak tekinthető. Ha figyelembe vesszük, hogy a hivatkozott objektumok megváltoztathatatlansága a referenciát hordozó objektum megváltoztathatatlanságából fakad (egyfajta "mély változhatatlanság"), akkor az alábbi objektum változó, mert hivatkozik egy List objektumra, amely lehet változó. Ha viszont csak magát a referencia értékét vesszük figyelembe, és nem az objektumot, amelyre mutat (egyfajta "felületi változtathatatlanság"), akkor ez az objektum megváltoztathatatlan, mert nem ad interfészt (metódust vagy nem -privát mező), amely lehetővé teszi bármely mezőjének kívülről történő módosítását (beleértve a List objektumra való hivatkozás értékét is).

class Panier { private final List articles; public Panier(List articles) { this.articles = articles; } public List getArticles() { return articles; } public int total() { /* retourne le prix total */ } }

Ha valaki biztosítani akarja, hogy a List objektum is megváltoztathatatlan, akkor az alábbi módosítás részben megoldja a problémát. Az osztályteremben PanierImmuablea lista nem változó: lehetetlen cikkeket hozzáadni vagy eltávolítani belőle. A cikkek azonban nem garantáltan változhatatlanok. Az egyik megoldás az, hogy minden egyes elemet felsorol egy konténer dekorátor tervezési mintába , hogy az változhatatlanná váljon. Egy másik megoldás az lenne, ha a metódus PanierImmuableutasításával nem engedjük, hogy a List objektum elemeire való hivatkozások elmenjenek az osztályból . return new ArrayList(articles);getArticles()

class PanierImmuable { private final List articles; public PanierImmuable(List articles) { this.articles = Collections.unmodifiableList(new ArrayList(articles)); } public List getArticles() { return articles; } public int total() { /* retourne le prix total */ } }

A példányainak átalakító osztályok (objektum típusok csomagolópapír primitív típusok) Integer, Long, Short, Double, Float, Character, Byte, Booleana megváltoztathatatlan.

A megváltoztathatatlan osztályok néhány egyszerű javaslat követésével valósíthatók meg.

Piton

Python, típus bool, tuple, str, bytes, frozenset, rangemegváltoztathatatlanok, és numerikus típusok int, floatés complex. A lista nem teljes.

Az objektumok tuplea heterogén objektumok megváltoztathatatlan listája a Pythonban. Láthatjuk a típust tuplea megváltoztathatatlan medálnak listés frozenseta változatlan medálnak set. Ellentétben azzal, amit megfigyelünk például a rubin nyelvben, a karakterláncok ( str) megváltoztathatatlanok. Bájt karakterláncok ( bytes) is, de van egy bytearrayváltozó típus .

Rubin

A szimbólum objektum a Ruby-ban megváltoztathatatlan, megjegyezzük:

:symbole

Rozsda

Alapértelmezés szerint a változók és az objektumok változhatatlanok vagy nem módosíthatók. A szimbólum változtathatóvá mutteszi őket.

Másolás írásra

Megjegyzések és hivatkozások

  1. (in) Megváltoztathatatlan objektumok  " , javapractices.com (hozzáférés: 2012. november 15. )
  2. Lásd: Adatmodell a Python nyelvi dokumentációban, és Beépített típusok a standard könyvtár dokumentációban.

Lásd is