fel
le

Az adatrejtés

Az adatrejtés azért szükséges, mert az objektum minden esetben felelős azért, hogy a hibátlan állapotából ne lehessen kizökkenteni.

Ennek során a kritikus mezőit kénytelen a külvilág elől elrejteni. Ugyanis egy el nem rejtett mezőt a külvilág nemcsak kiolvasni képes, hanem tetszőleges, akár hibás értéket is képes beleírni.

Védelmi szintek

Egy mező védelmét maga a fordítóprogram kell hogy biztosítsa oly módon, hogy eleve meggátolja egy védett mezőbe való írást. Nyilván tájékoztatni kell a fordítóprogramot a védelmi igényünkről.

A helyett, hogy újabb trükköket vezetnénk be, kihasználjuk a programozási környezetben jól ismert hatáskör fogalmát.

Amennyiben egy mezőt védeni szeretnénk a külvilág káros, ellenőrízhetetlen beavatkozásaitól, úgy egyszerűen a hatáskörét nem terjesztjük ki erre a területre. Hatáskörön kívül a fordítóprogram eleve meggátolja a mező elérését, így az értékének megváltoztatását is.

Sajnos, kissé átesünk a ló túloldarára. Ugyanis a hatáskörön kívül nem csak írni, de olvasni sem lehet a védett mező értékét, pedig néha arra szükség lenne. Ezzel a problémával később fogunk foglalkozni.

Három védelmi szintet ismerünk:

  • public
  • protected
  • private

A private védelmi szint

A mezők minden esetben valamely osztály belsejében kerülnek bevezetésre (deklarálásra). A private mező hatásköre nem terjed túl az osztályon. Ez a legszigorúbb védelmi szint.

Egy ilyen private mezőre csakis az osztály belsejében deklarált metódusok törzsében hivatkozhatunk. Az osztály metódusai szintén az osztály részei, így ők természetesen a legszigorúbb védelmi szint mellett is dolgozhatnak a mezővel.

Egy ilyen private mező az osztály sajátja. Csakis az osztály metódusai olvashatják és írhatják át az értékét. Ennek megfelelően az osztály teljes kontrollt kap a mező értéke felett. A mező, és rajta keresztül az osztály invariáns tulajdonságának megtartása biztosítható.

A private védelmi szintet gyakran használjuk, és a külvilág felé szükség esetén metódusokat biztosíthatunk a kezelés (olvasás, írás) biztosítására. Ugyanakkor megjegyezzük, hogy a private mező értékének kiolvasása függvényen keresztül nyilván lassúbb,mint közvetlenül a memóriából.

Hasonlóan, az érték írása valamely metóduson keresztül (és az új érték beírás előtti ellenőrzése) nyilvánvalóan lassúbb, mint ha azt direkt módon írnánk a mezőbe. Amennyiben a beleíró kódban megbízunk, úgy ezen folytonos (és felesleges) ellenőrzés a program futási sebességét kedvezőtlenül (és feleslegesen) befolyásolja.

A választás gyakran nehéz:

  • biztonság: a mező legyen private, és minden írás és olvasási művelet csakis az osztály metódusain keresztül történjen. Ekkor a biztonság maximális, a futási sebesség minimális.
  • sebesség: a mező ne legyen private, az írás-olvasás nem csak az osztály metódusai számára megengedett közvetlen módon. Ekkor a biztonság gyengül, a futási sebesség nő.

A döntést alapos tervezési megfontolások segíthetik.

A protected védelmi szint

Az ilyen védelmi szintű mező hatásköre kiterjed a mezőt bevezető osztályra, és annak minden leszármazottjára.

A protected védelmi szint indokolt olyan mezők esetén, melyek elérésére a továbbfejlesztett osztályokban (gyermek-osztály) is szükséges. Ezen mező elérése a működés szempontjából kritikus, vagy nagy sebességű kezelésre van szükség.

A protected védelmi szint nagyon is megfelelő! Az eredeti objektum-osztály könnyedén megőrízheti invariáns tulajdonságát, hiszen a mezői biztonságban vannak a külvilág káros beavatkozásai ellen. A továbbfejlesztett osztályok is elérhetik ezen mezőket direkt módon, és akár hibás értékeket is helyezhetnek el bennük, de ez akkor nem az eredeti osztály hibás működését jelenti, hanem az új, továbbfejleszett osztályét! Ez már azonban nem az eredeti osztály fejlesztőjének a problémája!

Ugyanakkor ne használjuk a protected védelmi szintet, csak átgondolt esetekben. Ugyanis a továbbfejlesztett osztályban sajnos nincs lehetőség a védelmi szintet visszaállítani private-ra. Az örökölt mező védelmi szintje is öröklődik, és nem megváltoztatható! Ezért ha az ős osztály protected-é nyilvánított egy mezőt, akkor az a gyermek-osztályban is protected lesz, és ő is így adja azt tovább.

Vegyük figyelembe, hogy ha egy mezőre private metódusok hivatkoznak, amelyek rosszul működnek ha hibás érték kerül a mezőbe, úgy ezen protected szint mellett problémákra lehet számítani. Ugyanis a gyermekosztály nem tudja semmilyen módon lecserélni a private metódusainkat, így nem tudja azok viselkedését sem hozzáigazítani az esetleges hibás értékhez sem. Egy ilyen esetben nagyon gyakori, hogy a továbbfejlesztett osztályban ezen private metódusok újra megírására kerül sor. Mivel azonban a private metódusok nem virtuálisak, így nem csak ezen metódusok újraírását kell elvégezni, hanem minden más, őket használó metódusokat is!

A public védelmi szint

A public védelmi szint a mező hatáskörének kiterjesztését jelenti a teljes programkódra. Ekkor nem csak az adott osztályban, s nem csak a továbbfejleszett osztályokban, hanem tetszőleges, teljesen idegen osztályokban is közvetlenül lehet ezen mezőket írni és olvasni.

Ezen védelmi szint a legmegengedőbb. Ha egy mezőre ekkora hozzáférést biztosítunk, akkor ez azt jelenti, hogy az osztály metódusai ezen mezőben lévő értékkel kapcsolatban abszolút nem bíznak meg, vagy számukra nincs semmi jelentősége.

Az alapértelmezett védelmi szint

Amennyiben egy mezőnek nem jelölünk ki explicit módon védelmi szintet, úgy az alapértelmezett védelmi szint a private.

Lehet, hogy azért nem jelöltük meg a védelmi szintet explicit módon, mert elfelejtettük. Ugyanakkor a private azért kellemes, mert ezen védelmi szint mellett sem a továbbfejlesztett osztályokban, sem azokon kívül nem lehet a mezőre hivatkozni. Ha erre szükség lenne, akkor ez elég hamar ki fog derülni, hiszen a többi kód írójának hibaüzenetet fog jelezni a fordítóprogram. Ekkor tudják figyelmeztetni az osztályt kódoló programozót a hibáról.

Fordított helyzetben, ha egy private mezőt helytelenül public védelmi szintre helyezné automatikusan a fordítóprogram - úgy a hiba lehet hogy sosem derülne ki (esetleg meg sem próbálják használni ezt a mezőt), vagy azt hinnék, hogy a publikus mezőbe tetszőleges érték írható, mivel az nem kritikus. Ekkor a hibás működés esetleg csak futás közben jönne elő. A futási közbeni hiba okának felderítése pedig mindíg nehezebb, mint a fordítási hiba okának felderítése. Védelmi szintek alkalmazása metódusokra

Amennyiben a védelmi szinteket (private, protected, public) mezőkre alkalmazzuk, úgy a mezőhöz való hozzáférést (írás, olvasás) tudjuk szabályozni. A mezőkhöz való hozzáférést a hatáskörének szűkítésével lehet befolyásolni. Mgát a védelmet a fordítóprogram biztosítja - amennyiben a mezőhöz az engedélyezett hatáskörén kívül próbálunk a forráskódban hivatkozni - úgy a fordítóprogram megtagadja a programunk lefordítását.

A védelmi szintek nem csak mezőkre, hanem metódusokra is alkalmazhatóak. A hatás megegyezik - a metódusok hatáskörét tudjuk befolyásolni. Egy metódust csak a hatáskörén belül lehet meghívni. Ezért egy private metódust csak az osztály belsejében lévő másik metódusból tudunk meghívni. Hasonlóan értelmezhető a protected és public védelmi szint jelentése is metódusok esetén.

Jellemző, hogy private metódusok olyan segédfüggvények, amelyeknek a meghívását nem engedélyezzük külső, osztályon kívüli kódból. Az ilyen metódusok paramétereinek értékét sokkal felületesebben is elég ha leellenőrízzük, hiszen a metódus meghívása belső, megbízható kódból történik.

A public metódusok elérhetőek külső, megbízhatatlan kódból is. Ezen metódusok minden esetben alaposan vizsgálják meg a paraméterek értékeit, a paraméterek és az objektumpéldány belső állapota közötti összefüggéseket, mielőtt tevékenységet hajtanának végre. Az ilyen metódusok mindíg egészséges gyanakvással kell éljenek a külvilág irányába, nehogy a helytelen paraméter-értékek felhasználása miatt az objektum példány hibás állapotba kerüljön.

Amennyiben egy public metódus a külvilágból kapott paraméter-értékeket el szeretné utasítani, akkor kivétel feldobásával kell jeleznie ezt. A kivételt a hívó, külvilágbeli pont elkaphatja, és lekezelheti.

Hernyák Zoltán
2013-03-17 18:08:11