ORMs and the likes - the good, the bad, the ugly

ORM-urile sunt o componenta esentiala pentru developeri, fie ca vorbim de Doctrine 2 in PHP, Active Records in Rails sau SQLAlchemy in Python sau altele. Toate au parti bune, parti proaste si chestii care nu ne plac, dar le acceptam pentru ca nu avem incotro.

Pentru ca eu prestez in mare parte PHP (Symfony mai exact) si m-am intrigat carcoteala lui @msd intr-un alt topic o sa vorbesc despre Doctrine, dar nu cred ca trebuie sa ne limitam la o librarie sau chiar limbaj. Putem invata si din ce se intampla prin ograda vecinilor :smile:.

From PHP Extractor - unealta pentru arhive

Legat de Doctrine (pe care il uram cu mult patos pana la versiunea 2.0) nu prea am nemultumiri. Mi se pare ca atat timp cat nu te indepartezi de scopul unui ORM si iei considerare best practice-urile isi face treaba bine. Si pe sistemul nu schimba ceva care functioneaza pentru tine, folosesc in continuare Doctrine. Din cand in cat mai arunc cate o privire peste alte librari (Propel 2, Eloquent) dar nu m-au convins.

1 Like

Nu ințeleg prea bine subiectul pe care-l vrei discutat dar te susțin. Sunt pro ORM-uri și cred că este natural într-o lume din ce în ce mai complexă să folosești tehnologii noi care le abstractizează pe cele vechi sau care se folosesc de convenții pentru a ușura complexitatea. Este foarte normal ca cele noi să nu fie suficient de mature dar ăsta nu este un motiv pentru care să ne încăpățânăm să le folosim pe cele vechi. Până la urmă avem niște minți destul de limitate și ar fi bine să le folosim cât mai productiv.

Am un hashmap in baza de date

{
  type: 'alien'
, age: 'unknown'
, image: '(╯︵╰)'
...
}

// ... <- reprezinta 389 fields

Scopul meu este sa modific hashmap-ul din baza de date, nu vad de ce este mai simplu sa lucrez cu un ORM cand adaug un layer de complexitate in plus.

Creez o clasa Creature careia ii adaug metode, pe care s-o extind cu Alien ca sa adaug alte metode ca in final sa ajung sa lucrez pe hashmap-ul din DB.

Nu este mai simpla varianta in care creez functii / module care sa lucreze direct cu DB-ul si sa sar peste Clase si Extinderea de clase?

Care ar fi avantajele unui ORM, exceptand comoditatea?

1 Like

“E uşor a scrie versuri. Când nimic nu ai a spune” ← Eminescu, nici el n-a avut incotro

1 Like

@andySF
Ca sa clarific subiectul: incerc sa aflu ce ORM-uri mai foloseste lumea si de ce. Poate descoper ceva nou sau primesc argumente care sunt relevante pentru mine dar nu le gasesc in prezentarea librariilor.

@navaru
Un ORM devine cu adevarat util doar in daca il cuplezi si cu alte componente.
Cel mai des intalnit exemplu pentru mine: am o entitate definita in Doctrine, entitea este folosita de un form builder, care gestioneaza semi-automat binding-uri si validari. Pot sa fac asta si manual, dar as ajunge sa am destul de mult cod redundant in functie de “tabelele” cu care lucrez. Nu mai zic ce parere minunata are PHPUnit cand incerci sa testezi astfel de cod.

Dacă ai de gând să faci un script care se conectează la o bază de date, atunci poate e prea mult un ORM. În restul celorlalte cazuri, când ai de făcut un strat separat pentru a comunica cu bază de date este infinit mai util să folosești un ORM deoarece:

  • Posibilitatea de abstractizare. Este cel mai important aspect din care rezultă toate cele de mai jos. Avantajele aici sunt de la portabilitate până la decuplarea totală de baza de date.
  • Sintaxa Context.Clasă.Obiect.Proprietate este mult mai elegantă/lizibilă/simplă decât select Obiect from Context...
  • După ce ai configurat ORM-ul, timpul pentru dezvoltare este cu mult mai mic. Plus că avantajează DRY.

Lista poate ar mai continua dacă chiar trebuie să găsesc avantaje dar cred că abstractizarea este cel mai important beneficiu pe care-l poți câștiga.

Și vorbind de comoditate eu văd lucrurile așa. Cel mai bun programator din lume trebuie să fie și cel mai comod.

lucrul cu bazele de date inseamna sa iei o (singura) coloana dintr-o (singura) tabela.

Daca sunteti amabili (ca draguti sunteti), as avea rugamintea sa nu mai folositi expresii de genul:

  • “devine cu adevarat util doar”
  • “este infinit mai util să folosești”

Cand m-am apucat de programare, neavand cunostinte sau studii similare, am inceput sa caut pe net. Am dat de un forum de php romanesc si am inceput sa citesc pe acolo. Si o persoana cu talent didactic si literar scriseze in cateva posturi despre importanta folosirii UML in programare.

Am zis “fratiwere pirateaza o carte cu UML si invata abstractizari”, daca asta recomanda omu pt. incepatori, am citit vreo 300 de pagini despre diagrame si liniute (mi s-a parut interesant sa fiu sincer).

Imi aduc aminte ca m-am inscris la un webinar despre Zend Framework si am postat in chat ca intrebare “how do you describe the flow of a website in UML?”. Intrebarea a fost ignorata, si am zis, ba ce noob sunt, toti stiu asta, deasta nu se raspunde.

In final m-a lamurit un tip pe softpedia si mi-a recomandat PHP Power Programming.

http://devforum.ro/t/un-must-watch-despre-software-development-foarte-interesant/595

3 Likes

Daca incercai sa inveti Java (EE mai ales) si intrebai de UML altele ar fi fost reactiile :smile: . Eu nu stiu decat un programator PHP care sa fi folosit UML si asa doar pentru ca lucrese destul de mult in Java si Visual Basic (parca).

Revenind la subiect, uite un articol despre ORM Misconceptions.

Uite ca am gasit un exemplu util care exemplifica ce incercam eu sa explic: https://github.com/vrana/notorm - este luat dintr-un comment din articolul recomndat de @redecs

foreach ($software->application()->order(“title”) as $application) { // get all applications ordered by title
echo “$application[title]\n”; // print application title
echo $application->author[“name”] . “\n”; // print name of the application author
foreach ($application->application_tag() as $application_tag) { // get all tags of $application
echo $application_tag->tag[“name”] . “\n”; // print the tag name
}
}


lasa-ma sa inteleg... faci o interogare intr-o tabela si dupa aia, pentru fiecare rand faci o interogare pentru tag-uri?

Păi uite, am luat un proiect la optimizat ca omora un server cu 8 cores si 8 gb ram
Programatorul desi a folosit un framework MVC, n-a facut nici un fel de MVC
SQL-urile sunt in controller, nu tu prepared statements, "select * " pt un singur camp de tip INT, count in php in loc de select count(field) … chestii d’astea.
Veneau datele din mysql cu 600-700Mb/s si iesea din php cu 5Mb/s o incarcare de “controller” facea cateva mii de query-uri (nu randuri, query-uri :smile: )

Fa-i refractor la asta. Şi pana la refractor, intelege modelul din db. myisam chior, nu tu foreign keys nu tu nimic.
Si in “controller” de 15.000+ linii care e facut cu elseif tot, e o placere, mai ales ca trebuie sa schimb schema.
Acu cu Doctrine, aveam invalidare de cache la update, delete. Aveam migrations. Puteam sa fac eager loading la chestiile care trebuie si lazy la optionale. Stiam ca tot ce tine de mapare e intr-un singur fisier si nu alerg prin zeci samd
Scenariu d’ala de fuck my life. Si eu iau banii abia cand ating goal-ul de 200ms response time :))

1 Like

application_tag() ia toata tabela si apoi face loop prin ele

Proiectul are [documentatie][1], daca nu e clar exemplul, uite aici: http://www.sitepoint.com/database-interaction-made-easy-with-notorm/

Eu daca as mai scrie php, as folosi ceva similar, nu stiu cat de solia este libraria
[1]: http://www.notorm.com/#api

Incerc sa iti explic si eu de ce cred ca un ORM este util.

  • Poti sa iti setezi event-uri
    Poti defini ca de fiecare data cand se salveaza in baza de date informatii sa fie preprocesate si in final salvate sub o alta forma. De exemplu poti face validari si acestea vor fi encapsulate in model. Modificarile pe model vor fi facute in orice controller (sau parte a aplicatiei) dar logica validarii va fi intr-un singur loc, fara sa ai riscul de a uita sa o adaugi sau sa se comporte diferit in parti diferite ale aplicatiei.
  • Poti sa creezi atribute fake (computed)
    In baza de date poti sa ai ceva date complexe dar uneori ai nevoie de atribute derivate din cele existente, fara sa fie nevoie sa fie salvata aceasta informatie in baza de date.
    De exemplu intr-o clasa ai elevi si lista de elevi este salvata dar atribut calculat este cati sunt baieti si cati sunt fete.
  • Poti sa definesti relatii standardizate intre colectii
    Aici este o chesti mai mult de standardizare si claritate. Relatii de genul “One to One”, “One to Many”. Cat si de lejeritate in implementare.
  • Folosind principii cunoscute si deja implementate scazi riscul de avea erori in codul de baza

Daca vrei sa iti raspunzi singur la intrebarea aceasta citeste documentatia de la cateva ORM-uri si vezi daca ce este implementat te atrage in vreun fel.

http://laravel.com/docs/eloquent

1 Like

@hydrarulz merci de raspuns

Inafara de “Poti sa definesti relatii standardizate intre colectii”, care tine mai mult de ‘data modeling’ si e putin subiectiv, restul le poti face si fara un ORM, folosing module separate.

Am folosit Mongoose (ORM in JS) la multe proiecte, dar am renuntat dupa ce am lucrat la un proiect complex care nu folosea. Am vazut ca e mai simplu sa modifici si sa faci teste, eu personal nu recomand folosirea lor, decat daca esti novice / comod si nu stii sa faci altfel.

Daca e cinva interesat de intrebari specifice putem discuta pe exemple “Cu un ORM eu implementez asa [exemplu], cum ar fi altfel?”, poate ar fi mai util.

Normal că poți face totul fără un ORM. Dar e ca și cum ai săpa o groapă cu o lopată în loc să folosești un utilaj specializat.

Ai auzit părerile noastre fie ele mai bune sau mai rele dar sunt curios care sunt părerile tale despre un ORM. De ce nu ai folosi unul?

2 Likes