Unelte și strategii refactorizare Django

Salutare! Am sub mentenanță un proiect dezvoltat in Django. Este un Dashboard clasic în care se crează administratori cu diferite nivele de permisiuni ce pot la rândul lor crea utilizatori și niște obiecte de tip licențe.

Utilizatorii și licențele nu sunt relevante. La început exista un singur tip de Administrator, să ii spunem root. Pentru asta a fost creată o aplicație Django (pentru cei ce nu cunosc Django asta este echivalentului unui pachet/componentă). Aici s-au definit niște endpoint-uri cu diferite functionalități.

Când a fost nevoie de un nou tip de Administrator, pentru a salva timp, s-a duplicat aplicația de admin existentă și s-a modificat cod pe colo, pe colo.

Astfel s-au creat 3 tipuri de aplicații. Fiecare face cam același lucru doar că un pic diferit. Dacă vreau acum să adaug o functionalitate nouă administratorilor trebuie să duplic codul pentru toate cele 3 aplicații. Plus teste unitare pentru toate.

Mă gândesc serios să reunesc cele 3 intr-o singură aplicație. Momentan îmi fac o strategie și poate aveți ceva recomandări pentru mine.

Există tool-uri ce mă pot ajuta? Am urmărit o parte din seria de tutoriale ale lui Christopher Okhravi, recomandată de iamtz, de acolo mi-a venit idea folosirii de diagrame UML pentru a vizualiza ce metode utilizează fiecare aplicație.

1 Like

Presupanand ca folosesti un ide(PyCharm) cred ca ar trebui sa stie sa iti genereze el diagrama UML

Da, folosesc Pycharm dar din păcate doar versiunea comercială oferă extensia Diagrame.

Am găsit un software simpluț DIA, merge și pe Ubuntu. O să schițez acolo diagramele apoi am să caut un tool cu care să fac o diferență intre fișere, să pot compara metodele.

Si noi folosim Django serios (adica zi de zi mai multi membri ai echipei) de ani de zile, dar principiile astea nu sunt legate in mod special de Django sau de Python:

  • scrie niste teste automate care iti merg pe structura actuala. Testarea automata e cruciala in orice refactorizare. Test clientul HTTP din Django e numai bun.
  • inteleg ca se preteaza o clasa de baza sau, cel mai probabil, mai multe (view, operational etc.) si treci gradual parti din aplicatie pe noua structura: clase care mostenesc clasa de baza si ofera ~aceeasi functionalitate
  • asigura-te ca trec testele tot timpul si mai adauga teste pentru diverse corner cases pe care le identifici cand lucrezi
  • fa asta gradual in asa fel incat sa poti face release-uri frecvente, o tehnica ce te poate ajuta: https://martinfowler.com/articles/feature-toggles.html
  • nu te apuca sa resrii tot pe idee ca faci un release big bang, vei omori proiectul (si/sau utilizatorii): https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/

Binenteles ca asta ia timp si bani, ceea ce multe proiecte nu au. :slight_smile:

2 Likes

Ah, si gandeste cu ocazia asta, daca tot faci refactorizare, o structura de “separation of concerns”, te ajuta la reutilizarea codului, la testare, cod mai curata si usor de citit.

Noi ne asiguram ca modelele se ocupa doar de date si evitam sa bagam logica acolo.
View-urile sa trateze doar partea de HTTP. Si mai e un layer de “operations” unde iti bagi logica.

Adica un MVC, ca nu ajunge MTV-ul lui Django in unele situatii. :slight_smile:

Lucrurile pot fi blury, dar macar sa tinzi spre asta si sa fii constient cand iei anumite decizii.

Până la urmă am creat manual niște diagrame. Recomandarea ta @Cosmin_Popescu a fost bună, dar din păcate meniul diagrame din Pycharm este disponibil doar pentru varianta cu licență (ce îmi lipsește pentru moment).

Am creat deci niște diagrame cu programul Dia. Le-am organizat astfel încât să am o vedere de ansamblu asupra aplicațiilor. Așa am observat ce clase sunt reutilizate/duplicate.

Pe mai departe am creat o nouă aplicație ce va lua locul celor 3 existente. Am folosit programul Meld Diff Viewer pentru o analiză comparativă între view-urile duplicate (programul mi-a permis să fac o analiză pe 3 fișiere simultan). Așa am observat ce anume trebuie parametrizat pentru a face un merge între cele 3 surse de cod.

Aveam deja teste unitare ce acoperă 80% din aplicație. Am creat primul view și am început rând pe rând să mut referințele url către acesta. La fiecare modificare rulam teste. Am repetat asta până când toate referințele către view-urile duplicat au fost eliminate.

Rezultat: mii de linii de cod mai puțin, mai puține teste unitare (fiecare view duplicat avea și teste duplicate), code duplication drastic redus.

@adrian-a. Observ că în acest proiect majoritatea logicii(<-am scris corect?) este în view-uri dar există câte ceva și în modele. Pe viitor mă gândesc să îmbunătățesc și calitatea codului. Multe metode/funcții sunt custom și ar putea fi înlocuite de funcționalități built in Django, analizele de Sonar dau și ele niște recomandări bune și acel “separation of concerns” de care vorbești nu sună chiar rău. Și mai am ceva planificat și pentru testele unitare, dar pentru asta deschid un topic nou (:

1 Like

Ma bucur ca ai reusit. :slight_smile:
Am folosit si eu Sonar. Este foarte bun si se instaleaza ca plugin.

Pentru sonar folosesc Docker:

  • zaquestion/sonarqube-python
  • zaquestion/sonarqube-scanner