Távolodni a mágiától - vagy: miért nem akarom tovább használni a Laravel-t?

Itt az ideje, hogy változtassak az általam használt eszközökön. És elmondom miért!

Először is biztosítani akarom, hogy tudjon a szándékaimról. Nem próbálok rágódni a Laravelről, vagy arról, hogy miért lehetne jobb más keretrendszer.

Ez a cikk nagyon szubjektív. Elmondom a gondolataimat, és megpróbálom rávenni, hogy gondolja át a keretrendszerét is. És amikor újraértékelés után ragaszkodsz Laravelhez, az rendben van. Nem áll szándékomban átalakítani az embereket a Laravel-től más keretrendszerre vagy nyelvre. De fontos, hogy alaposabban megnézze, és megbizonyosodjon arról, hogy mit és miért használ.

Bevezetés

Körülbelül 2 éve dolgozom a Laravel-lel. Mindig élveztem, hogy milyen egyszerű volt egy alkalmazást felpörgetni és percek alatt elindulni. Olyan sok hasznos eszközt kínál a dobozból. A konzol parancsai minden szempontból támogatják Önt a kódolás során. Osztályokat generálnak, állványokat a hitelesítéshez és még sok minden mást.

De minél mélyebbre megy, és minél nagyobbak lesznek a projektek, annál bonyolultabbá válik a fejlesztés a Laravel segítségével. Vagy hadd fogalmazzam meg újra: annál jobb eszközök fogják elvégezni a munkát. Nem is mondom, hogy csak Laravel hibája. Részben annak is köszönhető, hogy a PHP nincs túl jól megtervezve.

Most kezdjük!

Beszédes ORM

Ha már dolgozott Laravel-lel, akkor biztosan tud az Eloquentről. Az ORM az alapértelmezett telepítés. Nagyon sok ügyes funkcióval rendelkezik. De a kialakítása szükségtelenül bonyolulttá teszi az alkalmazást, és megakadályozza, hogy az IDE megfelelően elemezze a kódot.

Ez részben a használt Active Record ORM mintának, részben annak köszönhető, hogy az Eloquent meg akarja menteni a fejlesztőt attól, hogy további kódokat kelljen írnia. Ehhez sokat enged a fejlesztőnek a nem oda tartozó modellbe.

Jó szándéknak hangzik, de ezt egyre jobban nem szerettem.

Nézzünk meg egy példát:

Az első dolog, amit lát, hogy nincsenek tulajdonságok a modellen. Ez lényegtelennek tűnik, de számomra ez nagy különbséget jelent. Mindent „varázslatosan” injektálnak az osztályba a táblázat metaadatainak elolvasásával. Természetesen az IDE segítség nélkül nem érti ezt. És esélye sincs másként megnevezni tulajdonát, mint oszlopai.

Most nézze meg a hatókör módszerét. A Laravel felhasználói számára teljesen világos, hogy mit csinál. Ha meghívja ezt a módszert, a megadott WHERE záradék hozzáadásával lefedi az alapul szolgáló SQL lekérdezést.

Láthatja, hogy nem statikus. Ez azt jelentené, hogy ez a módszer az osztály egy meghatározott objektumán működik. De ebben az esetben nem . A hatókör meghívásra kerül egy lekérdezéskészítőn. Ez semmi köze a modell tárgy maga. Megmagyarázom, hogy miután megtudta, hogyan szokta hívni ezeket a hatóköröket:

Olyan statikus módszert hív, amelyet popular()soha senki nem definiált. De mivel Laravel meghatároz egy módszert __call()és __callStatic()módszert, rajtuk keresztül kezelhető. Ezek a módszerek továbbítják a hívást egy lekérdezés készítőnek.

Ezt nem csak az IDE nem érti. Ez megnehezíti az újrateremtést, összezavarhatja az új fejlesztőket, és a statikus elemzés is nehezebbé válik.

Ezenkívül, amikor ilyen módszereket alkalmaz a modelljén, megsérti a SOLID S-jét. Ha nem ismeri ezt, a SOLID egy rövidítés, amely a következőket jelenti:

  • S Ingle felelősség elve
  • O toll / Zárt elv
  • L iskov Substitution Principle
  • A szegregáció elve
  • D ependencia inverzió elve

Az Eloquent használatakor a modelljeinek több felelőssége van. Ez tárolja az adatbázisod adatait, amit a modellek általában csinálnak, de van benne szűrési logika, esetleg válogatás és még sok más is. Te ezt nem akarod.

Globális segítők

A Laravel jó néhány globális segítő funkcióval rendelkezik. Úgy tűnik, nagyon praktikus, és igen, ők is praktikus.

Csak azt kell tudnia, hogy feláldozza függetlenségét ezért a készségért, és globális névtere szennyeződik. Ez ritkán vezet konfliktusokhoz, de ennek elkerülését inkább előnyben kell részesíteni.

Nézzünk meg néhány példát. Itt van egy lista három segítő módszerről, amelyekre van szükségünk, de amelyekre nincs szükségünk, mivel vannak jobb alternatívák:

  • app_path()- miért? Ha szüksége van az alkalmazás elérési útjára, kérdezze meg az alkalmazás objektumát. Típusú tippeléssel kapja meg.
  • app()- mi? Nincs szükségünk erre a módszerre. Injektálhatjuk az alkalmazáspéldányt!
  • collect()- Ez létrehozza a Gyűjtemény osztály új példányát. Csak egy objektumot hozhatunk létre egyedül.

Még egy konkrét példa:

A Laravel globális request()segítőjét használjuk a POST adatok lekérésére és a modellünkbe való beépítésre attribútumként.

A globális segítő használata helyett tip Requestobjektumot írhatunk be paraméterként a vezérlő metódusába. A laraveli diszpécser tudja, hogyan juttassa el hozzánk a szükséges tárgyat. Ezzel meghívja a módszerünket, és nem kell segítőt hívnunk.

És tehetünk egy lépést tovább, hogy még jobban elválasszuk egymástól. A Laravel PSR-7 kompatibilis. Tehát ahelyett, hogy a Request objektumra utalna, írja be a tippet is ServerRequestInterface. Ez lehetővé teszi, hogy a teljes keretrendszert bármivel lecserélje, amely kompatibilis a PSR-7-tel. Ebben a módszerben minden működni fog. Ez kudarcot vallana, ha továbbra is a segítő módszereket használja. Az új keretrendszer nem érkezne a segítő módszerrel, ezért át kell írnia a kódjának ezt a részét.

Ritkán kapcsolja át az egész keretet, de van, aki igen. És akkor is, ha te talán sosem kapcsoljuk, mégis fontos az átjárhatóságot. A lehetőség a függőségek injektálására és tömör adatáramlásra a függőségek és adatok kijavítása és kijavítása helyett. Megkönnyíti a tesztelést, a refaktorálást és szinte mindent.

Örültem, amikor elolvastam, hogy a Laravel 5.8-as verzióval a karakterlánc és a tömbsegédek eltávolításra kerülnek a magról, és külön csomagba kerülnek. Ez egy jó első lépés. De a dokumentációnak el kell kezdenie az összes segítő funkció használatának elrettentését .

Homlokzatok

Az utolsó rész érvei itt is szerepet játszanak. A homlokzatok jó eszköznek tűnnek néhány, nem igazán statikus módszer gyors eléréséhez. De még egyszer belekötnek a keretbe. Ezeket a függőségek kézi megoldására használja, ahelyett, hogy a környezetre utasítaná őket.

Ugyanez vonatkozik a bonyolultságra is, ha mindent átadunk a mágikus módszereknek.

Mivel IDE-támogatásról beszéltünk, tudom, hogy néhányan a barryvdh-től irányíthatnak az IDE-segítő csomaghoz. Nem kell. Már ismerem ezt a csomagot. De miért is van rá szükség? Mivel egyes tervezési döntések a Laravelben egyszerűen nem jók. Vannak olyan keretek, ahol erre nincs szüksége. Vegyük például a Symfony-t. Nincs szükség IDE segítő fájlokra, mert jól megtervezett és megvalósított.

A homlokzatok helyett ismét használhatnánk a függőség-injektálást, mint az előző példában. Valódi tárgyunk lenne, és valódi módszereket hívhatnánk fel rá. Sokkal jobb.

Még egyszer mondok egy példát:

Ezt könnyen kitakaríthatnánk. Mondjuk Laravelnek, hogy adjon be egy a-t, ResponseFactoryés adja át nekünk az aktuális kérést:

Most sikeresen kiküszöböltük a homlokzatok használatát vezérlőnkből. A kód még mindig tiszta és kompaktnak tűnik, ha nem is jobb, mint korábban. És mivel vezérlőink mindig kiterjesztik az általános Controllerosztályt, mindent egy lépéssel előrébb tehetünk, ha a válaszgyárat átköltöztetjük erre a szülőosztályra. Szükségünk van rá minden más vezérlőosztályban.

Úgy hallottam, hogy egyesek „túl sok konstruktor-paramétert” adnak meg érvként, ami ellen mindent be kell injektálni. De ezzel nem értek egyet. Először csak a függőségek és így a komplexitás elrejtése. Ha nem tetszik, hogy 10-20 argumentum van a konstruktorban, akkor igaza van.

A megoldás nem varázslat. Annyi függőségre van szükség egyetlen osztályban, ami azt jelenti, hogy ennek az osztálynak valószínűleg túl sok felelőssége van. Ahelyett, hogy elrejtené ezt a bonyolultságot, refaktorozza meg azt az osztályt. Ossza fel újakra, és javítsa az alkalmazás architektúráját.

Érdekes tény: létezik egy igazi tervezési minta, a „Négyzet bandája” könyvében bemutatott „homlokzati minta”. De teljesen más jelentése van. A Laravel homlokzatai lényegében statikus szolgáltató lokátorok . A névadás ezt egyszerűen nem közvetíti. A különböző dolgok azonos elnevezése szintén megnehezíti a projektek architektúrájáról folytatott vitákat, mert a másik fél valami egészen mást várhat e név mögött.

Következtetés

Jöjjön a vége. Hamarosan írhatok egy nyomon követést arról, hogy mely technológiákat szeretem manapság használni. De pillanatnyilag hadd foglaljam össze a tanultakat:

Laravel megközelítése, hogy mindent a lehető legkönnyebbé tegyen, jó. De nehéz kijönni, amikor alkalmazásai fejlettebbek lesznek. Jobban szeretem a félelmetes IDE támogatást, az erősebb gépelést, a valós tárgyakat és a jó mérnöki munkát. Lehet, hogy még visszatérek a Laravelhez, amikor egy kisebb alkalmazást akarok írni.

Sok pontom nemcsak Laravel hibája. Felcserélhetném azokat a részeket, amelyek nem tetszenek, például az ORM-et. De ehelyett csak átkapcsolom az eszköztárat, ahol az alapértelmezések jobban megfelelnek az igényeimnek. Nem látom értelmét egy olyan keretrendszer használatának, ahol több időt kell töltenem annak elkerülésére, hogy csapdákat állítsam elő a rossz tervezéshez, mint az alkalmazásom fejlesztéséhez. Más keretek és eszközök jobban megtervezett alapértelmezettel és kevesebb varázslattal rendelkeznek.

Tehát egyelőre elbúcsúzom Laraveltől.

Köszönöm az idődet. Nagyra értékelném a hozzászólásokban folytatott szép beszélgetést, és természetesen nyitott vagyok a kérdéseire és javaslataira.

PS: Külön köszönet Marco Pivettának a korrekt olvasásért és a további információkért!

Szerkesztés: 2019. március 1 .:

Amióta cikkem felkerült a Reddit-re, létrehoztam egy Reddit-fiókot, hogy válaszoljak néhány megjegyzésre. A fiókom nem az, amelyből a cikket közzétették, hanem ez: //reddit.com/u/nschoellhorn

Szerkesztés: 2019. március 13 .:

Ha idáig elolvastad, megnézheted a Twitter-profilomat is. Köszönjük, hogy továbbra is érdeklődik a téma iránt! Mindig nyitott vagyok a produktív beszélgetésekre, ezért kérjük, lépjen kapcsolatba nyugodtan itt vagy a Twitteren.