Despre un proiect
Posted by adragomir on februarie 19, 2008
Filed Under Știință și Tehnică, Tehnologie | 10 Comments
Any software problem can be solved by adding another layer of indirection.
Make things as simple as possible, but not simpler.
Simplitatea in ingineria software e o tema despre care s-a scris foarte mult. Daca vreti o tratare completa a subiectului, este o lista de materiale de la sfarsitul articolului. Postul asta e o lista de observatii si idei (de bine) legate de simplitate si complexitate (accidentala) in software observate personal si care reapar in multe proiecte la care am lucrat.
Despre dezvoltare
Peste tot in articol, voi folosi termenii cu un inteles larg. Prin dezvoltare, inteleg “majoritate activitatilor care nu au legatura cu pasul de deployment”
.
Primul lucru ar fi “scrie!” Cand faci un modul, incearca intotdeauna sa ai in cap o descriere completa, si sa intelegi tu exact cum se foloseste. E ceva in neregula daca nu poti sa il explici unui coleg. E irelevant daca ai sau nu un proces formal pentru specificatii. Capacitatea unui programator de a transmite informatia asta altor persoane este in schimb esentiala.
Majoritatea proiectelor din ziua de azi se scriu in limbaje orientate obiect (modul de gandire OO intra si in proiecte scrise in limbaje procedurale, precum C). Literatura legata de arhitectura si design orientat obiect este extensiva, si sunt multe lucruri aplicabile. Dar nu fa designul la aplicatie ca un exemplu pentru o carte de design patterns! Foloseste strictul necesar.
Decuplare: nu iti crea clasele astfel incat sa fie legate foarte strans. Foloseste interfete, dar nu fa ierarhii foarte adanci. Sunt foarte putine cazuri unde ierarhii adanci de clase sunt necesare. Poti sa te gandesti la principiul asta pe dos: “cat de greu imi e sa smulg o bucata de cod si sa o inlocuiesc cu altceva ”. Identifica bucatile care sunt candidate pentru asta si construieste-le decuplat.
Nu fa o ierarhie stricta de clase, cu multe subdiviziuni. Dar lasa-ti posibilitatea sa injectezi testabilitate in sistem (obiecte “paralele” care mimeaza o anumita functionalitate?). Daca proiectul tau e intr-un limbaj dinamic (python, ruby), scapi mai ieftin.
Nu lasa astronautii sa te sperie!. Incearca sa intelegi o arhitectura si, chiar daca esti fortat sa o folosesti, retine ce e prost in ea si ce ar fi mai bine adaptat pentru pproiectul tau.
Nu fa codul prea structurat! Poti sa folosesti un hash, nu e nevoie sa creezi neaparat o clasa. Atunci cand creezi o clasa, conceptul modelat “ingheata” pentru restul programului. Poti sa iti ascunzi codul care creeaza entitati compuse, dar nestructurate in functii.
Prototipuri: chestii inutile (le vei arunca/rescrie), lente (de obicei), scrise repede si prost, care iti dovedesc ca sistemul merge si e corect. Daca esti mult mai productiv intr-un anumit limbaj, prototipeaza modulul la care lucrezi in acel limbaj. Codul asta pe care il vei arunca te ajuta sa iti ordonezi extrem de bine toata problema in cap. In loc sa vanezi buguri cu pointeri, o sa te poti concentra exact la problema pe care vrei sa o rezolvi.
Prototipurile nu se refera la cod. Poti sa faci prototipuri la interfete, API-uri etc. Poti sa le faci simple sau complete (tracer bullets), care eventual sa se integreze cu restul sistemului.
Daca trebuie sa rescrii un prototip, sau codul e prea greu de scris, uita-te la pattern-ul Alternate Hard and Soft Layers (sau “interpreter pattern” in alte carti). Daca e foarte greu sa rescrii totul in c++ / java, rescrie “bucla interna” sau modulele care fac munca grea in ceva rapid. Pastreaza codul care “conduce” functionalitatea in ceva high level si usor de schimbat si inteles.
Fara legatura cu articolul: daca nu stii inca un limbaj de scripting, invata unul. Nu e un moft, e realitatea industriei. Sunt o gramada, gratis si bune.
Unele proverbe pe care le invatam la gradinita au corespondente in software: “nu te lega la cap daca nu te doare”. Inteleg asta in doua traduceri diferite: unu, nu fi prea destept, doi, nu optimiza prematur.
“Desteptaciunea” se refera la ultimul algoritm despre care ai citit si pe care il introduci / implementezi in software, eventual si cu un comentariu de genul ” you are not supposed to understand this ”. O metoda simpla e de preferat uneia foarte subtile dar greu de inteles.
Optimizarea prematura are si un corolar, si la asta o sa ma refer: “Intai fa-l bine, si apoi repede”. Sunt multe tehnici de optimizare, si multe dintre ele iti complica (putin) codul. Gandeste-te la ele, tine-le in minte, dar nu actiona pana cand nu observi probleme, si exact unde sunt. Majoritatea analizelor de performanta scot cate un hotspot intr-un loc surprinzator.
Nu reinventa roata. Aici, in functie de buget / timp / complexitate, exista mai multe metode de a rezolva o problema : sa cumperi / sa o rescrii / sa introduci un proiect gratis. Alegerea depinde de la caz la caz, dar uita-te la prima si la a treia optiune.
Nu uita de tehnologiile open source! Daca licenta nu e o problema, evalueaza cu atentie tehnologia. Modul de gandire “tehnologia nu e sustinuta de o firma, ergo e proasta” nu e valid, fara o evaluare. La open source totul e … sursa, iar asta te ajuta sa ai mai multa incredere atunci cand introduci o dependinta in proiect. Dar tine numarul de dependinte la un minim!
Flexibilitatea e inca un domeniu in care sunt ignorant. Intrebarea e “cat timp aloc pentru flexibilitate?”. Flexibilitatea se leaga de atat de multe concepte, incat e greu sa raspunzi la ea. E vorba de flexibilitate la adaugat functionalitati? Sau dimpotriva, o functionalitate clara / fixa, dar flexibilitate in codebase pentru a schimba conectori / algoritmi etc?
Despre proces
Orice fel de proces / metodologie ai avea, e o intrebare esentiala: “cunoaste si respecta TOATA echipa mea acest proces?”. Daca ai un singur Scrum Master / Agile Ninja / XP Doctor, nu te va ajuta prea mult daca echipa nu stie despre ce e vorba. Chiar daca nu folosesti o metodologie formala cap-coada, sunt cateva observatii care functioneaza:
Comunica in modul cel mai simplu posibil. Daca lumea e in acelasi birou, fa sedinte scurte, in care fiecare sa inteleaga la ce lucreaza alta persoana. Pentru echipe distribuite nu te zgarci la marit numarul metodelor de comunicare (video / audio / irc). Cea mai buna pentru echipa ta va fi pur si simplu folosita, iar restul nu.
Review de cod: prin email / ym / scula de code review. Asigura-te ca alta pereche de ochi se uita pe cod, vei gasi multe probleme (inclusiv de integrare) intr-o faza incipienta.
Foloseste source control, foloseste un bug tracker. Nuff said.
Un commit in sistemul de source control trebuie sa faca un singur lucru: rezolva un bug / adauga o functionalitate. Dar nu fa un commit care modifica jumatate din cod odata. Motivul e foarte simplu: daca commit-urile sunt atomice, e mult mai usor sa faci revert. Si pentru alti membri ai echipei e mult mai usor sa integreze multe bucati mici.
Pastreaza linia principala de dezvoltare (aka trunk sau mainline) corecta! Nu trebuie un proces foarte strict, dar asigura-te ca inainte sa faci commit raspunzi la niste intrebari simple: “se mai compileaza?”, “am testat functionalitatea?”, “trebuie sa anunt pe cineva care se integreaza cu ce am facut eu?”.
Testare: orice fel de testare ai vrea sa folosesti, nu pierde foarte mult timp pierdut in evaluari. Construieste-ti schela de testare cu orice fel de scula, dar asigura-te ca e usor de folosit. Programatorii sunt “lenesi” (accentuez ghilimelele) si asta e bine, conduce la simplitate / automatizare. Duce si la faptul ca programatorii sunt MULT mai sensibili la calitatea unei interfete (fie GUI, fie API) decat restul oamenilor.
Proiecteaza in general “programabilitate” in sistem. GUI-urile sunt utile, insa nu te ajuta sa rezolvi problema de a inlantui procese / lua rezultate din teste. Orice scula folosesti, asigura-te ca se poate folosi si din linia de comanda. In lumea de azi, e destul de simplu, majoritatea sculelor au doua fete, fie cu interfete grafice, fie pot fi “conduse” de scripturi in linia de comanda.
Daca procesul e prea rigid, scapa de el sau schimba-l. Dar pastreaza sistemul de source control
.
Despre deployment
Pe desktop, sunt cateva intrebari: “Pot sa reduc instalarea programului meu la un proces de copiere?”. Nu te baza pe chestii magice, si sute de modificari in environmentul in care ruleaza programul, pentru ca sigur o modificare nu va merge, si ca urmare, nici programul.
Cu legatura la update-uri, nu prea mai exista lume cu modemuri (nu ma refer la DSL). Nu te chinui sa faci un sistem de update foarte complicat. In multe cazuri, ajunge sa iti pui utilizatorii sa ia o noua versiune. Dar foloseste tehnologii existente daca e mai simplu!
Web-ul rezolva bineinteles problem deployment-ului si aduce altele. Contra simplitatii in cod, investeste timp si scrie / foloseste un sistem de deployment. Ca chestii minime, ar trebui sa stie sa impinga update-uri pe mai multe tipuri de servere, pentru ca vei avea nevoie de asta (staging, qe etc).
Legat de builduri, daca un build dureaza 5 minute pe o masina de dezvoltare, schimba scula de build. Sparge proiectul, refactorizeaza modulele dar fa astfel incat sa se compileze simplu si rapid. Programatorii se enerveaza repede pentru chestii din astea
Cel mai important lucr ar fi automatizeaza. De la rulare de teste in diverse configuratii, pana la facut upload de zip pe site-ul firmei.
Despre sisteme “legacy”
Nu toata lumea porneste proiecte acum. Mai sunt multi “balauri” ascunsi prin banci / institutii / old iron systems. Precum caracteristici, sistemele astea (nu toate!) sunt mari, fragile, greu de deploy-at, greu de testat. Nu dispera, si nu introdu mai multa entropie. Ia problemele pe masura ce apar, nu te gandi cum sa rescrii totul de la inceput.
Chiar daca sistemul e plin de ferestre sparte, repara-le pe masura ce le gasesti. O strategie de a rescrie tot e de foarte multe ori catastrofala sau imposibila. Atunci cand schimbarile sunt localizate, repara / scrie teste / refactorizeaza numai bucata respectiva.
Altceva?
Toate observatiile astea se supun regulii “sa nu fim tampiti”. Nu folosesc cuvantul in sensul propriu, ci in sensul de om care taie firul in 14 atunci cand nu e inca timpul pentru asta. Software-ul se schimba, de unde si numele, si aproape niciodata nu vei putea sa te feresti de invechirea codului, documentatiei.
Nu trebuie sa faci research-ul de “ce probleme au cele 5 distributii de server LDAP pe linux, cate resurse folosesc, si ce librarii de LDAP exista in limbajul in care scriu proiectul?” ACUM. Dar pune-ti intrebarea “pot sa schimb sistemul de autentificare?” si planuieste in consecinta.
Gandeste-te la proiect ca un agricultor american care traieste din subsidii guvernamentale: “o sa primesc bani buni pentru codul pe care NU il scriu”. Pastreaza codul scris la un minim de simplitate si vei putea sa il schimbi si sa il intretii mult mai usor.
Vor fi proiecte la care sa nu se poate folosi cod extern, sau care trebuie sa se supuna unei arhitecturi bizantine din motive pe care nu le puteti controla. Incercati sa aplicati principiile astea local, unde au sens, si sa pastrati codul cat de simplu posibil. Lupta-te cu chestiile care nu au sens, dar alege-ti bataliile!
Adevarul e undeva la mijloc. Caracteristicile proiectului la care lucrezi primeaza intotdeauna unor observatii generale.
Dar pastreaza lucrurile simple!
Index of /docs:
- The Art of Unix Programming, Eric Steven Raymond
- “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
- The Pragmatic Programmer: From Journeyman to Master, Andrew Hunt, David Thomas
- Joel on Software
- Quotations about simplicity in software development
- Pagini pe Portland Pattern Repository legate de subiect
Toate observatiile din articol sunt observate personal, si sper sa ajute pe cineva sa nu isi mai “juleasca genunchii”. Sunt multe alte lucruri, unele pe care nu le stiu, altele pe care le-am uitat, dar le fac intuitiv. Cred ca cel mai important e sa scrieti, modificati si cititi cod bun si rau pana cand toate astea intra in reflex. Poate trebuie sa pun asta la inceputul articolului
.
Practicati simplitatea zi de zi si o sa ajungeti sa aveti o intuitie “zen” legata de simplitate si eleganta in software.
Scuze pentru inflorituri stupide / exprimari stangace ale unui programator semicoerent
.
Ganduri?
/A
Comments
10 Responses to “Despre un proiect”
Leave a Reply


Si zi-mi A…ndrei, …. Tu chiar aplici toate astea? Ai o lista mare pusa pe perete la tine in birou? Sau te-ai prins ca intr-adevar cam aici se ajunge dupa multe tentative mai mult sau mai putin reusite de a sistematiza scrierea de software? Eu zic ca in foarte multe companii cu echipe sudate formate din absolventi de facultate si cu cel putin 3 ani de experienta cam asa se lucreaza.
Dar tine si de management, de constrangeri bugetare si de termene limita – si strict din experienta mea stiu sigur ca un manager bun de proiect + control eficient de calitate = diferenta dintre un proiect de succes sau nu. Indiferent de geniul programatorilor si de… alte detalii tehnice!
A, a-propos, s-au cam rarit comentariile la voi pe blog! Parca nici voi intre voi nu va mai comentati aproape deloc iar domnisoarele de la HR care stateau permanent de paza pe aici si pe terte bloguri, deh, sa nu apara vreun comentariu cu tenta negativa, parca au intrat in pamant. Asa e cand nu se mai ocupa nimeni de imaginea publica a companiei in ochii potentialilor angajati! Dar cine sunt eu sa imi pese, nu?
Nu, nu le aplic tot timpul. Si nici nu pot fi aplicate tot timpul, asta era unul din ideile articolului.
Dar ideea e ca ma gandesc mereu la astea. Si cred ca daca te gandesti la lucrurile astea, poti sa micsorezi timpul in care le inveti si le faci sa devina reflex.
Problema “cum sa facem un proiect de succes” mi se pare monstruoasa de abordat, si nici nu cred ca exista un singur raspuns.
Dar am incercat sa ma concentrez pe o serie de observatii care au un singur scop: sa pastreze proiectul si procesul simple. Nu am vazut inca proiecte care sa nu poata beneficia cumva de asta.
“Eu zic ca in foarte multe companii cu echipe sudate formate din absolventi de facultate si cu cel putin 3 ani de experienta cam asa se lucreaza.” …
Aia trei ani fac toata diferenta intre jungla si un birou in care se poate respira. Din nefericire sunt foarte multi si absolventi, si cu “experienta”, care lucreaza exact pe dos, si sustin sus si tare ca asa e bine…iar suturile le paseaza discret celorlalti membri ai echipei.
-c
Fain articolul. Cred că mi-era şi mai bun dacă venea cu măcar vreo 2 luni în urmă, mi-ar fi prins bine şi pe la şcoală. Într-adevăr, multe din chestiile astea ajungi să le aplici/deduci instinctiv, dar nu strică niciodată să le mai scrie cineva, chiar şi un „programator semicoerent”
PS: Nu ştiu ce a fost cu siteul în ultima vreme, dar au fost prea multe erori de conectare la baza de date şi/sau timeout-uri în ultimele 4 zile
The pursuit of truth and beauty is a sphere of activity in which we are permitted to remain children all our lives.
- Einstein
Un post foarte bun si la obiect. Majoritatea principiilor enumerate se studiaza de obicei si la majoritatea facultatilor cu profil informatic din Romania ( tehnica “prototip”, abordarea in cascada, bottom-up, extreme programming etc. ) dar consider ca trebuie sa treci prin toate starile de frustrare, de incercare ca sa respecti temeinic principiile astea, si chiar daca ai incerca sa le respecti, tot ti-ar scapa ceva. Sunt pus in fata unui proiect personal pe care vreau sa-l incep ( si sa-l termin ) de mult timp si sunt foarte multe lucruri de facut la el ( e vorba de un website in php – de php de ce nu ati adus vorba? Sunt prea multi “pehaspisti” prin zona ? ) si de asemenea mentin un sistem de payment gateway prin paypal la care acum mi-am dat seama ca nu am lucrat extrem de organizat, desi sistemul merge bine. UML, ceva ?
@florin: ma bucur sa aud ca lucrurile astea se studiaza acum si in facultate! Cred ca sunt la fel de importante ca si structuri de date / algoritmi.
Cel mai graitor exemplu pentru simplitate mi se pare UNIX/Linux, ca un intreg. Nu se aplica toate particularitatile de design la toate proiectele, dar sunt cateva proprietati care sunt esenta “truth and beauty” in unix: “mechanism, not policy”, “80/20″, modularitate, fail-fast, “single point of truth” etc.
Cred ca sublimate la conceptul lor de baza, isi cresc aplicabilitatea peste tot.
Sincer am un mare dubiu ca in vreo facultate de la noi se preda despre extreme programming altceva decat afirmatia ca exista + prezentarea succinta a principiilor (cu care nu ajungi prea departe). Ma mai indoiesc ca vreo facultate te pregateste pentru vagoanele de bs pe care le vei incasa in primul proiect legacy serios de care vei da cu nasul tau fin si naiv de proaspat absolvent. Sau pentru faptul ca jumatate din business logicul omenirii este stocat in fisiere Excel sau mai rau, Filemaker.
Iar managementul impecabil + control eficient de calitate sunt ele bune, doar ca aplicate la o gramada de gunoi nu vad ce aport semnificativ ar putea sa aduca. Programatorii buni au rolul lor in tot acest ecosistem, si anume un rol vital.
Sau cine stie, poate ca-s eu prea batran si am vazut prea multe “rele”, ar trebui sa ma impuscati ca sa nu ma mai chinuiesc.
@Adrian: Nu stiu cat de batran esti, dar acum 2-3 ani curs de project management la Universitatea din Bucuresti – Fac. de Informatica. Avea, intr-adevar, ca suport principal “Software Project Management – Bob Hughes and Mike Cotterell” – care e formal “all the way”. Totusi a avut o introducere buna intr-o paleta larga de metodologii printre care si agile (XP, SCRUM), dar si chestii de gen PSP.
Aici este o arhiva cu descrierea cursurilor pentru fiecare an pe ultimii cativa ani: http://fmi.unibuc.ro/ro/plan_invatamant/
Daca te astepti ca studentii sa iasa din facultate direct cu experienta e alta poveste.
Din seria de citate celebre, mie imi place cel mai mult cel al lui Antoine de Saint Exupéry:
“It seems that perfection is reached not when there is nothing left to add, but when there is nothing left to take away”.