SmartObject
A SmartObject éveken át fejlesztette a PHP objektumok viselkedését. A PHP 8.4 verziótól kezdve minden funkciója beépült magába a PHP nyelvbe, így teljesítve történelmi küldetését a modern objektumorientált megközelítés úttörőjeként.
Telepítés:
A SmartObject 2007-ben jött létre, mint forradalmi megoldás az akkori PHP objektummodell hiányosságaira. Amikor a PHP számos objektumorientált tervezési problémával küzdött, jelentős fejlesztéseket és egyszerűsítéseket hozott a fejlesztők munkájába. A Nette framework legendás részévé vált. Olyan funkcionalitást kínált, amelyet a PHP csak sok évvel később ért el – az objektumtulajdonságok validálásától a kifinomult hibakezelésig. A PHP 8.4 megjelenésével befejezte történelmi küldetését, mivel minden funkciója a nyelv natív részévé vált. Figyelemreméltó módon 17 évvel előzte meg a PHP fejlődését.
A SmartObject érdekes technikai fejlődésen ment keresztül. Eredetileg Nette\Object
osztályként
implementálták, amelyből más osztályok örökölték a szükséges funkcionalitást. Jelentős változás jött a PHP
5.4-gyel, amely bevezette a trait-ek támogatását. Ez lehetővé tette az átalakulást Nette\SmartObject
trait-té, ami nagyobb rugalmasságot hozott – a fejlesztők olyan osztályokban is használhatták a funkcionalitást, amelyek
már örököltek egy másik osztályból. Míg az eredeti Nette\Object
osztály megszűnt a PHP
7.2 megjelenésével (amely megtiltotta az osztályok ‚Object‘ szóval való elnevezését), a Nette\SmartObject
trait tovább él.
Nézzük át azokat a tulajdonságokat, amelyeket egykor a Nette\Object
, majd később a
Nette\SmartObject
kínált. Mindegyik funkció jelentős előrelépést jelentett a PHP objektumorientált
programozásában a maga idejében.
Konzisztens hibaállapotok
A korai PHP egyik legégetőbb problémája az objektumokkal való munka következetlen viselkedése volt. A
Nette\Object
rendet és kiszámíthatóságot hozott ebbe a káoszba. Nézzük meg, hogyan működött eredetileg
a PHP:
A Fatal error leállította az alkalmazást anélkül, hogy bármilyen reakcióra lehetőség lett volna. A nem létező
tagok csendes írása figyelmeztetés nélkül súlyos hibákhoz vezethetett, amelyeket nehéz volt felderíteni. A
Nette\Object
minden ilyen esetet elkapott és MemberAccessException
kivételt dobott, lehetővé téve a
programozóknak, hogy reagáljanak és kezeljék ezeket a hibákat:
A PHP 7.0 óta a nyelv már nem okoz elfoghatatlan fatal error-t, és a PHP 8.2 óta a nem deklarált tagok elérése hibaként kezelendő.
„Did you mean?“ segítség
A Nette\Object
egy nagyon hasznos funkcióval érkezett: intelligens javaslatokkal elgépelések esetén. Amikor
egy fejlesztő hibát vétett egy metódus vagy változó nevében, nemcsak jelezte a hibát, hanem segítséget is nyújtott a
helyes név javaslatával. Ez az ikonikus üzenet, amely „did you mean?“ néven vált ismertté, órákat spórolt meg a
programozóknak az elgépelések keresésében:
Bár a mai PHP-nek nincs beépített „did you mean?“ funkciója, ezt a kiegészítést a Tracy biztosítja. Sőt, az ilyen hibákat automatikusan javítani is tudja.
Tulajdonságok ellenőrzött hozzáféréssel
Jelentős újítás, amit a SmartObject hozott a PHP-ba, az ellenőrzött hozzáféréssel rendelkező tulajdonságok voltak. Ez a koncepció, amely olyan nyelvekben általános, mint a C# vagy Python, lehetővé tette a fejlesztőknek, hogy elegánsan szabályozzák az objektumadatok elérését és biztosítsák azok konzisztenciáját. A tulajdonságok az objektumorientált programozás hatékony eszközei. Változókként működnek, de valójában metódusok (getter-ek és setter-ek) reprezentálják őket. Ez lehetővé teszi a bemenetek validálását vagy az értékek generálását olvasás időpontjában.
A tulajdonságok használatához szükséges:
- A
@property <type> $xyz
annotáció hozzáadása az osztályhoz - Getter létrehozása
getXyz()
vagyisXyz()
néven, setter létrehozásasetXyz()
néven - A getter és setter public vagy protected láthatóságú legyen. Opcionálisak – így létezhetnek csak olvasható vagy csak írható tulajdonságokként
Nézzünk egy gyakorlati példát a Circle osztályon, ahol a tulajdonságokat használjuk annak biztosítására, hogy a
sugár mindig nem negatív szám legyen. A public $radius
-t tulajdonságra cseréljük:
A PHP 8.4 óta ugyanez a funkcionalitás elérhető property hooks segítségével, amely sokkal elegánsabb és tömörebb szintaxist kínál:
Extension methods (Kiterjesztő metódusok)
A Nette\Object
egy másik érdekes koncepciót hozott a PHP-ba a modern programozási nyelvekből – az
extension methods-t. Ez a C#-ból kölcsönzött funkció lehetővé tette a fejlesztőknek, hogy elegánsan bővítsék a
meglévő osztályokat új metódusokkal anélkül, hogy módosítaniuk kellene azokat vagy örökölniük kellene belőlük.
Például hozzáadhattak egy addDateTime()
metódust egy űrlaphoz, amely egy egyéni DateTimePicker-t
ad hozzá:
Az extension metódusok nem bizonyultak praktikusnak, mert az editorok nem ajánlották fel a nevüket, sőt jelezték, hogy a metódus nem létezik. Ezért a támogatásuk megszűnt. Ma már általánosabb a kompozíció vagy öröklődés használata az osztályfunkcionalitás kiterjesztésére.
Osztálynév lekérdezése
A SmartObject egyszerű metódust kínált az osztálynév lekérdezésére:
Reflexió és annotáció hozzáférés
A Nette\Object
hozzáférést biztosított a reflexióhoz és az annotációkhoz a getReflection()
és getAnnotation()
metódusok segítségével. Ez a megközelítés jelentősen egyszerűsítette az osztály
metainformációkkal való munkát:
A PHP 8.0 óta lehetséges a metainformációk elérése attribútumok formájában, amelyek még több lehetőséget és jobb típusellenőrzést kínálnak:
Method getterek
A Nette\Object
elegáns módot kínált metódusok átadására, mintha változók lennének:
A PHP 8.1 óta használható az úgynevezett first-class callable syntax, amely még tovább viszi ezt a koncepciót:
Események
A SmartObject egyszerűsített szintaxist kínál az események kezeléséhez. Az események lehetővé teszik az objektumoknak, hogy értesítsék az alkalmazás többi részét állapotuk változásairól:
A $this->onChange($this, $radius)
kód egyenértékű a következő ciklussal:
Az átláthatóság érdekében javasoljuk a $this->onChange()
mágikus metódus kerülését. Praktikus
helyettesítője a Nette\Utils\Arrays::invoke függvény: