Essee loetavast koodist

04.05.2008  |  Gunnar

Sander tegi otsad lahti loetava koodi teemat puudutavate kannetega. Hetkel on neid juba tükki kaks, Muutujate nimetamine: kõige raskem osa programmeerimisest? ja Veel raskeid asju programmeerimisel: kommentaarid. Lisan juurde omapoolse kokkuvõtte loetava koodi kõrgest kasust, mida saavad need, kes selle sügavamad võlud on enda jaoks avastanud.

Miks räägivad XP mehed sellist juttu, et pole vaja igasuguseid hädavajalikke pabereid koostada? On nad peast hullud? Või on siin mingi konks? Üks neist hädavajalikest paberitest on kindlasti süsteemi tehniline dokumentatsioon, mis kirjaldab viimse peensuseni lahti klassid ja kõik muu, mida kirjeldada annab.

Mina ei koosta enam ammu süsteemide kohta tehnilist dokumenti, mis kirjeldab klasse, liideseid ja struktuure ning nende atribuute, omadusi, meetode ja sündmusi tehnilisest poolest. Minu arust on selle mahuka dokumendi koostamine mõttetu lisatöö ja ajakulu. Ja nii palju kui on elu näidanud mulle taolisi dokumente, on nad alates esimesest dokumendi valmimise järgsest muudatusest kehtetu paberpakk ja kalli vihmametsa mõttetu raiskamine. Järjekordne auk maailma kopsus.

Minu seisukoht on see, et koostada tuleb ainult need dokumendid, millel on mõte - need dokumendid ei jää peale sündi kapinurka paberihunti ootama.

NB! Kindlasti tuleb tehnilise poole kohta koostada dokumendid, kus on kirjas süsteemi ülesehitus ning kirjeldatud kõik asjad ära äri seisukohast. Neist dokumentidest saavad aru kõik projektis osalevad inimesed.

Esiteks, pole vaja seda dokumentatsiooni seepärast, et selle sünkroonis hoidmine lähtekoodiga on progejate jaoks vastik lisategemine, mis segab keskendumist nendele probleemidele, mis päriselt ka lahendamist vajavad. Teiseks pole seda dokumenti vaja siis, kui kood räägib ise, mida ta teeb ja kui kood on dokumenteeritud kohas, kus ta ise asub. Tehniline dokumentatsioon koodi kohta ei huvita ei tellijat ega mänekaid - klassikalisel projektijuhil käib see nii või teisiti üle kõrvade.

Näide praktikast. Patsatas mulle kord postkasti postitus, et pangu ma nüüd siis kirja ka, et mis asi ja miks ja kuidas toimib. Ja tehku selle kohta siis see klasside dokumentatsioon kõigest. Oh aeg, oh inimesed, mõtlesin ma. Samas olin rahul - möödas oli mitu nädalat pingelist tegemist ja ongi ehk hea, et paar päeva saab mune laiaks istuda ja rahulikult klahve näppides kohvi rüübata. Aju rõõmsalt lontis ja pea õhtaseid mõtteid täis.

Halb suhtumine või? Ei olnud - mul istus selle dokumendi sisu kenasti koodis dokumentatsioonina juba ees. Viskasin selle kähku koodimise käigus valmis. Kui kodanikele ei sobi kena HTML, mis koodi dokumentatsioonist tekib, siis palun väga - ma võin selle käsitsi ju Word'i dokumendiks ümber visata.

Seda dokumenti järgmine inimene, kes minu koodiga tegeles, ei lugenud kordagi. Ehk esilehelt vaatas pealkirja. Tal polnud seda vaja - koodiga tegeledes oli see info tal ekraani peal juba olemas.

Vaatame nüüd kahte näidet. Neist teise kohta ma pikemaid kommentaare ei jaga. Kõik on ilmne, kood ütleb ise, mis ta teeb. Sinna otsa võtame kokku võidud, mida meile teine näide tõi. Sellele järgneb omakorda vabakava - kes tahab, kommenteerib, kes vajutab väsinult Back-nuppu, kes teebmidagi muud huvitavat. Aga, let's go!

Kuldne klassika

Kindlasti oleks vaja head seletust millelegi sellisele.

public double Do(ArrayList arr, double df)
{
    double s = 0;

    foreach(Invoice i in arr)
    {
        i.Total = df * i.Sum() + i.HFees;
        s += i.Total;
    }

    return s;
}

Mida võiks see jupp koodi teha? Nimi viitab sellele, et mida tehakse. Väga hea. Meetodi, mis midagi ei tee, ei oleks ju mõtet kirjutada... Okay, aga mis asub selle tabava nme taga? Sinna tuleb sisse mingisugune list mingite asjadega - mis asjadega, seda me ei tea. Ja tuleb ka df, mis iganes see ka ei ole. Järgmiseks on defineeritud keegi s, mille sisu jääb ka veel lahtiseks. Ja siis läheb tegemiseks.

Nüüd saame ühe grammi juba targemaks. Seal massiivis on eeldatavasti arved, sellele võiks anda viite klassi nimi Invoice. Järgmiseks arvutatakse välja Total, mis saadakse sel teel, et Sum korrutatakse selle müstilise df-iga läbi ja sellele lisatakse mingisugune asi, mille nimi on HFees. See HFees istub arve küljes ja vist tähendab midagi.

Kõigele lisaks tegeleb see meetod veel millegagi - nimelt liidab total-eid kokku ning tagastab need. Mis kontekstis see asi võiks olla - jumal seda teab, kui teab. Küll aga teame seda, et kui sellises meetodis on kuskil viga ja meil on meetodi kohta infot täpselt nii palju, siis peame me otsima kuskilt üles tolle eelmainitud paberipaki ja ajama seal tükk aega näpuga järge.

Näide praktikast. Pidin kunagi tegelema koodiga, kus puudus dokumentatsioon, polnud kommentaare ning meetodite ja klasside nimed olid suht segased ja mingeid lühendeid täis, mis olid otseselt kinni allistuvas aluspõhjas. Selle koodiga tegelemine oli väga vaevaline ning tänu sellele, et keegi ei vaevunud oma tegemisi ja nägemusi ka suusõnaliselt selgitama, oli eestvedaja poolt valmiv kood teistele seda segasem ning arusaamatum. Vaimselt suhteliselt mõttetu, igav ja laostav kogemus, sest väljakutse - tegeleda suht häguse psühhiaatriaga - ei pakkunud avastamise ega millegi valmistamise rõõmu.

Kui eestvedaja oleks kirjutanud iga klassi kohta kasvõi ühe inimkeelse selgituse, pannud kõikidele asjadele üheselt arusaadavad nimed, poleks kellelgi tekkinud ühtegi küsimust, millle vastamiseks poleks suitsupaus olnud piisav.

Kaasaegne klassika

Kaasaegna kood, mida kirjutavad need kummalised XP inimesed, on teistsugune. Idee on lihtne - kood peab sisaldama endas infot oma tegemiste kohta nii, et seda on võimalik lihtsasti käigult haarata. Kujutame nüüd ette, et me peame parandama vea, mis tekib järgmises koodis. Selle saime nii, et üks XP mees tuli ja tegi ülaltoodud meetodi ümber.

/// <summary>
/// Calculates totals of invoices.
/// </summary>
public void CalculateTotals(List<Invoice> invoices, double discountFactor)
{
    foreach(Invoice invoice in invoices)
        invoice.Total = discountFactor * invoice.Sum() + invoice.HandlingFees;
}

Et arvete nimistu põhjal summa arvutamine on teine toiming, siis selle tegevuse tõstis XP mees teise meetodi ja rookis koodist välja terve rivi kohti, kus sama arvutus oli järjekordselt sisse kirjutatud.

Muideks, sellest ülaltoodud koodist saate vist päris hästi aru. :)

Näide praktikast. DT-s oleme praktiseerinud hoolega seda, et kood oleks võimalikult hästi organiseeritud, võimalikult selge ja võimalikult loetav. Peame oluliseks seda, et inimene, kes pole vastava koodiga enne kokku puutunud, saaks koodi nähes võimalikult hästi aru, mida ja miks on seal tehtud. Selle lähenemisega oleme me võidumehed.

Mulle ei valmista mingit mure võtta hoidlast mõne jooksva .NET projekti lähtekoodi viimane versioon ning viia ennast kurssi sellega, mis on vahepeal toimunud ning mis asi miks ja kuidas töötab. Küsimusi on mul teistele oluliselt vähem kui mujal nähtud klassikalistes projektides.

Millised on me võidud?

Peamine võit, mille saavutame hästi loetava ja ennast kirjeldava koodiga, on ajaline kokkuhoid. Ja seda mitmel rindel.

  • Projekti on senisest oluliselt lihtsam kaasata uusi progejaid, sest tehnilise köögipoolega enese kurssi viimine, on väga lihtne.
  • Uute versioonide arendus algab lihtsamini, sest progejatel pole raske teha meeldetuletust sellest kuidas ja mis toimis.
  • Koodis leiduvaid vigu on oluliselt kergem parandada. Kujutage ette tavaolukorda ning võrrelge seda võõra linnaga, kus puuduvad tänavatel nimesildid ning teede ääres liiklusmärgid. Siin seda probleemi pole.
  • Et tegemist on inimkeelele lähedase keelega ning loogika vastab süsteemi tegevusala omale, siis tekib tellijatega suhtlemisel oluliselt vähem igasuguseid pudelikaelu ja möödarääkimisi.

Oluline lisaboonus on see, et kui kood on ka kõrgemal tasemel väga hästi organiseeritud, siis annab see progejatele tohutult hea ülevaate antud projekti valdkonna loogikast. See on see asi, mille leidmiseks tuleb muudel juhtudel kottida analüütikuid või tehnilisi disainereid ning tuhlata paksudes dokumentides.

Lõpetuseks

Loomulikult ei anna ka hästi organiseeritud kood 100% edasi tegevusalale vastavat teavet, kuid otste lahtitegemist lihtsustab see oluliselt. Samuti hoiame me aega kokku kõvasti ning teenime plusspunkte sellega, et oleme võimelised probleemide korral kiiresti reageerima.

Kui aeg teisendada rahaks, siis saaksime tulemuseks selle, et hinda tellija jaoks muutmata oleme teeninud ise paraja kasumi, ilma et teistel turul osalejatel oma hindadega elu raskemaks oleksime teinud. Selle ettepanekuga võid Sina - programmeerija - minna otse oma pealiku juurde ja öelda, et teeme nüüd nii. Kui hästi ei lähe, jääb ju kõik nii nagu praegu on ja kui läheb hästi, siis oleme võidumehed.

10 kommentaari sissekandele “Essee loetavast koodist”

  1. Lembit

    “Writing a detailed requirement spec up-front is a worst practice, despite being considered a best practice for the longest time. When you do this, you are building to specs, as opposed to building to what people actually need.”

    Scott Ambler, Practice Leader, IBM

    http://www.thestandard.com/news/2008/04/18/ibm-fixed-prices-it-projects-are-unethical

  2. Gunnar

    Ambler on ka päris hea kirjanik tehnilistel teemadel. Mina olen lugenud temalt sellist raamatut nagu Building Object Applications That Works. Ja riiulis ootavad oma järge veel mõned teosed. :)

  3. Sander

    Suurepärane on ju öelda, et spec tuleb jooksvalt. Ning siis leida inimene, kes suudab kliendile selgeks teha, et täpse info oma tarkvara kohta saate pärast, tähtaega projekti valmimisel ei ole, maksate meile jooksvalt kuni me ütleme, et nüüd on valmis. Edu…

    Ambleri kirjutis on imho selgelt in-house projektide kohta. Kui välja arvata Skype ja pangad, kui palju on Eestis (tarkvara-)firmasid, kes teevad karbitooteid või majasiseseks kasutamiseks suuri tarkvaratükke? Enamus firmadest on äriklientide ja riigi peal, eriti viimasele ei istu agiilne arendus kohe mitte. Parimal juhul saab projekti etappidena teha.

  4. Gunnar

    Koodile eelnevatest spetsidest ma siinkohal juttu ei teinud, see on teine teema. Mõttetuks kisuvad need spetsid, mis dubleerivad koodis toodut. Seda paberit ei loe klient kunagi, ehk mõnikord vaatab ja imetleb liblikate keeles kirja pandud lauseid ja tunnetab dokumendist õhkuvat salapära :)

    Mis puutub jooksva aja põhiselt tegemisse, siis sellega pole probleemi. Pikk etteplaneerimine on asi, mis sisaldab endas tohutult igasuguseid ebakõlasid, sest mida kaugemale liigume käesolevast hetkest, seda suuremaks läheb oletuste maht kõikides teemades. Ja nii sünnivadki need vahvad analüüsidokumendid, mille keegi hoolikalt valmis vorpis, kuid mis peatselt endas enam ilma oluliste muudatusteta midagi reaalset ei sisalda projekti seisukohalt.

    Lühikeste iteratsioonidega minek on kõvasti efektiivsem - oleme seda proovinud ja tulemused on hoopis vingemad. Siinkohal peaksin hoopis mina soovima edu neile, kes koostavad dokumente, mille sisust umbes 80% on muutmisele kuuluv huupi sihtimine. Klientidele annab lühikesi iteratsioone väga hästi põhjendada - lõppeks saavad ju nemad oma raha eest maksimaalset kasu, sest ei pea kinni maksma igasugust sehkendamist, mis kulub oletuste tegemisele.

    See on ka omaette pikem teema, millest võiks kande kirjutada. Samas - miks kirjutada? Et Eesti turg on kõvasti kinni vanaaja metoodikates, siis miks õpetada kasutama enda ärieeliseid :)

  5. Gunnar

    Ambleri kirjutise kohta nii palju, et pole vahet kas in-house või mitte. Mainitud teos kirjeldab põhitõdesid, mis kehtivad mõlemate arenduste kontekstis.

  6. Marek

    Oh Sander… millal sina kord IT kirjandust lugema hakkad ja süüvid ka metoodikate osas sügavamale. On nähtud küll ja küll projekte, kus üritatakse loodussedaustele suure hulga spetsifikatsioonidega vastu minna, kuid pärast esimest muudatust on hala lahti ning pärast süüdistatakse, et spetsifikatioonid polnud täiuslikud. Valede eelduste põhjal ei olegi võimalik midagi täiuslikku saada, nimelt inimesed ei ole suuteliselt arvestama kõigega ning seepärast täiuslikke spetsifikatsioone ei teki.

    Miks väledad metoodikad selles osas paremad on? Lihtsalt nad ei ürita kindlale konstandile (muutused on konstantsed maailmas) vastu hakata, vaid minna kaasa sellega. Ma usun, et oled isegi näinud olukordi, kus tarkvara luuakse spetsifikatsiooni järgi, kuigi kliendi vajadused on muutunud. Kliendi investeering ei too talle enam palju tagasi. Vastukaaluks on väledate metoodikatega kliendil suur eelis, ta saab need muudatused suhteliselt kiirelt. (Lisa boonus kliendile on see, et kui talle ei meeldi esimeste iteratsioonide tulemused, siis võib ta selle firmaga asja pooleli jätta ning võtta selle kuskilt mujalt ning aja ja raha kaotus on tunduvalt väiksem.)

    Miks Eesti firmad ei kasuta väledaid metoodikaid, on see, et nad ei suuda vajalike praktikaidki omaks võtta. Need probleemikohad on automatiseeritud testimine ja tarkvara hoidmine väljalaskevalmiduses. Lisaks on probleem ka mõttemaailmas. Mõistmaks, mis seal teisiti on, siis tasub Agile Manifesto läbi lugeda mõttega.

    Mis puudutab veel spetsifikatsioonide valmimist pärast tarkvara loomist, siis nii see ongi. Kirjutad sa varem või mitte, tegelik spetsifikatsioon saab ikka hiljem valmis.

    Ja Sander, kui sul töö kõrvalt aega leidub, siis võiksid vaadata S. W. Ambler’i ettekannet teemal “Are You Agile or Fragile” [http://video.google.com/videoplay?docid=490917380139552102], mis on läbiviidud agiilses mõttelaadis, ja lugeda ta veebilehel [http://www.agilemodeling.com/] olevaid artikleid.

  7. Sander

    Anonüümne Marek, arvan et olen lugenud täiesti piisavalt IT-kirjandust selleks et antud teemal rääkida. Küll aga olen nõus alati juurde lugema.

    Kui sa aru ei saanud (tundub küll nii), siis pidasin silmas koodile eelnevaid spetse. Ehk põhiliselt tarkvara arhitektuuri ja konstruktsiooni. Tsiteerides CC2′te, “Depending on the size of the project, construction typically takes 30 to 80 percent of the total time spent on a project. Anything that takes up that much project time is bound to affect the success of the project. /…/ Requirements and architecture are done before construction so that you can do construction effectively. System testing (in the strict sense of independent testing) is done after construction to verify that construction has been done correctly. Construction is at the center of the software-development process.”

    Vaata ka http://thedailywtf.com/Articles/The-Great-Pyramid-of-Agile.aspx , loomulikult ka http://www.softwarereality.com/lifecycle/xp/case_against_xp.jsp

    Agiilne arendus on tore. Aga see ei ole imerohi mis maailmas kõik sõjad ja näljahäda lõpetaks - ega ka arendusmetoodika mis alati ja igal pool sobiks. Hetkel käes olev projekt on agiilse arendusmudeliga - töötan kliendiga “käsikäes”, pidevalt suheldes ja vastavalt koodi kirjutades või muutes, testid jne. Antud projekti (hiidprojekti alamhulk) jaoks ideaalne lahendus.

    Aga nüüd kujuta ette, et haigla elushoiuseadmeid kontrolliv tarkvara tehakse agiilse metoodikaga. Või NASA läheks üle agiilsele arendusmeetodile, “Soovite et süstik ei plahvataks? Selge, lisame järgmises versioonis, homme saate”. Põhjusega ei kasutata XP metoodikat hiidprojektide juures - või projektides, kus reaalne tulemus on näha alles hilises arendusfaasis.

    Igal asjal on oma koht. Nagu ma korduvalt olen öelnud, ainult naiivik usub et XP/agiilne programmeerimine on alati ja kõikjal ainus ja õige lahendus.

  8. Sander

    Kusjuures - pärast eelmist kommentaari tuli pähe - miks on agiilse programmeerimise ja XP pooldajad alati halvustavad ja militantlikud? “Sa ei kummardagi agiilset programmeerimist? Sa oled küll amatöörist jobu, õpi juurde kuni sa aru saad, et agiilne programmeerimine on inimkonna suurim leiutis. Seni ära räägi tarkvaraarendusest.”

    Kas on agiilne metoodika tõesti nendearust nii nõrkadel jalgadel et vajab sellist suhtumist?

  9. Gunnar

    Lühikesi iteratsioone annab ka kriitilise tähtsusega tarkvara arendamise juures rakendada ja seal on see ehk isegi väga omal kohal, sest kontroll tarkvara funktsionaalsuse ja töökorra üle peab olema maksimaalne, sest nii ajaliselt kui ka rahaliselt on odavam rookida vead välja kohe, kui need tekivad. Ja mis kõige hullem - eelanalüüsis tehtud möödapanekut tulevad ka kiiresti välja. Selles mõttes on lühike iteratsioon igati vajalik asi. Analüüs on kriitilistel süsteemidel loomulikult pikem, kuid koodimise ja riliisimise kohta ei ütle see veel midagi.

    Selge on loomulikult see, et testimine on palju karmim ja aeganõudvam tegevus kriitiliste süsteemide korral. Siinkohal toetavad arendajate tegevust palju kirevam valik automaatseid teste pluss manuaalsed testid lisaks. Samas ei ütle seegi midagi selle kohta, kuidas koodi kirjutada. Okay, nii palju ütleb, et teste tuleb kõvasti rohkem kirjutada.

  10. Urmo

    See püramiidijutt pole mulle varem ette sattunud. Hakkamata XP vs muud metoodikad lahkama, tahaksin ainult öelda, et see püramiidiartikkel teeb sama vea, mida teevad ka mõned saurusmetoodikad - kasutab majaehituse analoogi. Eriti hea on veel püramiidi kui objekti näide, kuna see on topelteksitav.

    Ehituses ei tee sa kunagi nii, et poole ehituse ajal vahetad välja/muudad maja vundamenti või mõnd muud algetapis tehtud konstruktsiooni (karkassi, elektrisüsteemi, kui juba käib seinade värvimine). Tarkvaras on see võimalik ja tihtipeale ka vajalik. Püramiidi näitest tuleb see vastuolu veel paremini välja, püramiidi tipp läheks nagu kitsamaks, materjali on vähem ja ehitada oleks nagu ka lihtsam ( vanasti polnud, kraanad puudu:P ). Tarkvara ehitamine keerukuse kui tööjõukulu mõõtes on üldjuhul tagurpidi püramiid - alguses kasutatakse palju valmisklotse ja töömahukaim on konkreetse rakenduse kasutaja- ning äriloogika loomine.

    Teine suur erinevus tarkvaratootmises on see, et ehituse praktikad on suhteliselt paigas, spetsialiseerumine ääretult suur ja loodavate objektide keerukus võrreldes tarkvaraga reeglina oluliselt väiksem. Kunagi M.Fowler, kelle naine oli vist arhitekt, tõi hea analoogi: ehituse juures on projekteerimise/ehituse mahud rusikareegilna 10/90 %. Tarkvara puhul eelnevalt ehitusega võrreldavalt kõik valmis projekteerida tähendaks 90% projekteerimist ja 10% tarkvara tootmist. Seda mõtet jätkates, võtke mingi projekti juures arenduseks kuluv aeg ja korrutage see 10-ga. Ja siis minge otsige klient, kes selle oleks nõus kinni maksma.

Kommenteeri

sulge
Saada link e-postiga

© DT 2012 | Creative Commons Attribution-Noncommercial 3.0 License | WordPress