- Refaktorisanje poboljšava unutrašnju strukturu koda bez promjene njegovog ponašanja, izbjegavajući degradaciju i "špageti kod".
- Kontinuirana primjena smanjuje složenost, tehnički dug i greške, olakšavajući održavanje i proširenje softvera.
- Mirisi koda i statička analiza ukazuju na područja koja su kandidati za refaktorisanje, što bi trebalo riješiti automatiziranim testovima kao sigurnosnom mrežom.
- Moderna IDE-a, alati za analizu i dobre timske prakse omogućavaju sigurno refaktorisanje i u novim i u naslijeđenim projektima.
Refaktorisanje koda postalo je jedan od onih zadataka za koje svaki programer zna da ih treba obaviti, ali koji se često odgađaju jer "nije vrijeme" ili "popravit ćemo to kasnije". Problem je što to "kasnije" gotovo nikad ne dolazi, a kod na kraju postaje pravo minsko polje koje je teško održavati.
U svakodnevnom radu na razvoju softvera, provodimo mnogo više vremena čitajući i razumijevajući postojeći kod nego pišući nove stvari od nule. Zato je učenje šta je refaktorisanje koda, kada ga primijeniti i kako to učiniti bez ikakvih problema ključno za preživljavanje bilo kojeg umjereno velikog projekta i, prije svega, za sprječavanje da vaša kodna baza postane neupravljivo čudovište.
Šta je tačno refaktorisanje koda?

Kada govorimo o refaktorisanju, mislimo na modifikovanje unutrašnje strukture koda bez promjene njegovog spoljašnjeg ponašanja . Drugim riječima, nakon refaktorisanja, aplikacija bi trebala da nastavi da funkcioniše na potpuno isti način iz perspektive korisnika, ali će interno kod biti jasniji, jednostavniji i lakši za proširivanje.
Zamislite refaktorisanje kao sređivanje i preuređenje kuće bez promjene broja soba : premještate namještaj, rješavate se stvari koje ne koristite, reorganizujete ormare i sve činite mnogo ugodnijim za život, ali kuća ostaje ista. U kodu, ovo se prevodi u preimenovanje varijabli, izdvajanje funkcija, dijeljenje velikih klasa, uklanjanje duplikata ili poboljšanje dizajna kako bi bio lakši za održavanje.
Ključna karakteristika refaktorisanja je da se radi u vrlo malim i sigurnim koracima . Svaka mikro-promjena mora održavati sistem u radu. Stoga se niz malih transformacija povezuje zajedno, postižući značajno poboljšanje bez da sistem ostane neispravan danima.
U kontekstu profesionalnog razvoja, refaktorisanje je disciplinovana praksa: ne radi se o ponovnoj izgradnji sistema od nule , niti o uvođenju novih funkcija pod izgovorom "pošto već nešto popravljamo, mogli bismo promijeniti i ovu drugu stvar". Nova funkcionalnost se obrađuje odvojeno od internih poboljšanja dizajna, iako se ponekad preklapaju.
Nadalje, refaktoriranje je usko povezano s idejom čistog, čitljivog i održivog koda . Kod koji radi, ali je neproziran, dupliciran ili pretjerano složen, vapi za refaktoriranjem, čak i ako još ne propada u produkciji.
Zašto kod degradira: truljenje koda, miris koda i špageti kod
Čak i ako projekat počne "čisto", vremenom se kod može lako pogoršati, što dovodi do onoga što je poznato kao truljenje koda (erozija softvera) . Novi rokovi, promjenjivi zahtjevi, više timova koji rade na istim dijelovima, brze odluke za snalaženje... sve to ostavlja svoj trag.
Jedan od najpoznatijih rezultata ove degradacije je "špageti" kod : kodna baza ispunjena zamršenim zavisnostima, teško razumljivim skokovima u izvršavanju, ugniježđenim uslovnim izrazima i petljama svuda. To je vrsta koda gdje je svaka promjena zastrašujuća jer nikad ne znate šta ćete pokvariti.
Među elementima koji često pretvaraju kod u haos su pogrešno korišteni skokovi toka (poput starih GOTO naredbi), komplicirane for/while petlje i beskrajne if naredbe . Kada mnogi ljudi također "krpe" nešto što je već imalo nedostatke, rezultat je skup improviziranih, nepovezanih i vrlo skupih rješenja za reviziju.
Mirisi koda su upravo znaci da nešto nije u redu, čak i ako i dalje radi. Oni ne znače da program ne radi, već da postoje indikacije da bi struktura mogla biti mnogo bolja i da će, ako ne preduzmemo ništa, kvalitet nastaviti opadati sve dok čak i pokušaj modifikacije tog modula ne postane noćna mora.
Uobičajene zamke uključuju dupliciranu logiku, ogromne klase, izuzetno duge funkcije, pretjerano spajanje i neinformativna imena . Rano otkrivanje ovih grešaka i refaktorisanje čim se pojave sprječava napredak lošeg koda i na kraju zahtijevanje potpunog prepisivanja ili vrlo skupog remonta sistema.
Najčešće vrste refaktorisanja
Refaktorisanje nije jedna tehnika, već skup praksi koje možete primijeniti ovisno o problemu s kojim se suočavate. U zavisnosti od toga gdje se u kodu nalazi "miris" problema , jedna vrsta refaktorisanja će biti prikladnija od druge.
Strukturno refaktorisanje
Strukturno refaktorisanje se fokusira na poboljšanje interne arhitekture aplikacije : kako su klase, moduli i paketi organizovani i kako su odgovornosti raspoređene među njima. Njegov cilj je povećanje kohezije unutar svake komponente i smanjenje povezanosti između različitih komponenti.
Ova vrsta refaktorisanja uključuje zadatke kao što su dijeljenje klase koja radi sve na nekoliko manjih , premještanje metoda tamo gdje im je zaista mjesto, reorganizacija paketa ili uvođenje novih jasnih slojeva (na primjer, odvajanje domene, infrastrukture i prezentacije) kako bi se buduće promjene znatno olakšale.
Refaktorisanje duplikatnog koda
Dupliciranje je jedna od najčešćih zamki: kopiranje i lijepljenje sličnih isječaka koda na različita mjesta u početku se čini brzim, ali je izuzetno skupo za održavanje. Svaki put kada nešto treba promijeniti, morate se sjetiti svih postojećih kopija.
Refaktorisanje usmjereno na eliminisanje dupliranja obično uključuje izdvajanje metoda za višekratnu upotrebu ili kreiranje funkcija za višekratnu upotrebu , uvođenje zajedničkih klasa ili čak novih apstrakcija koje konsoliduju ponovljeno ponašanje. Na ovaj način, kada je potrebno modificirati logiku, to je potrebno učiniti samo u jednom trenutku.
Refaktorisanje imena i varijabli
Naizgled jednostavna promjena, poput preimenovanja varijabli, metoda ili klasa kako bi se bolje izrazila njihova svrha , može transformirati način na koji se modul razumije. Dobro ime štedi vrijeme i smanjuje vjerovatnoću grešaka zbog nesporazuma.
Ova vrsta refaktorisanja uključuje pregled kriptičnih ili generičkih identifikatora kao što su "podaci", "upravitelj" ili "proces", zamjenjujući ih imenima koja jasno opisuju funkciju svake komponente. Moderni IDE-ovi uveliko olakšavaju ovaj zadatak , jer omogućavaju automatsko i sigurno preimenovanje u cijelom projektu.
Refaktorisanje dizajna
Ponekad problem nije ime ili duga funkcija, već to što se cjelokupni dizajn ne skalira. Refaktorisanje dizajna ima za cilj preispitivanje hijerarhija klasa i odnosa između komponenti kako bi se poboljšala proširivost i smanjila složenost.
To može uključivati uvođenje odgovarajućih obrazaca dizajna, razdvajanje odgovornosti, enkapsulaciju poslovnih pravila ili kreiranje novih interfejsa koji omogućavaju dodavanje funkcionalnosti bez potrebe za modifikacijom bezbrojnih područja. Ideja je postići fleksibilnost bez povećanja složenosti razumijevanja sistema.
Refaktorisanje orijentisano na performanse
Iako nije najčešći tip refaktorisanja, ponekad je prioritet poboljšanje performansi kritičnog dijela aplikacije . U tim slučajevima, refaktorisanje se vrši s ciljem smanjenja vremena odziva ili potrošnje resursa, uz zadržavanje istog funkcionalnog ponašanja.
Ova vrsta promjene obično se zasniva na mjerenjima i profilima performansi : ne radi se o "optimizaciji za svaki slučaj", već o fokusiranju napora na stvarna uska grla i primjeni dobro opravdanih lokalnih poboljšanja.
Prave prednosti dosljedne primjene refaktorisanja
Refaktorisanje nije hir ili estetski hir: ono ima vrlo konkretan uticaj na životni vijek softvera i svakodnevni rad razvojnog tima. Kada se radi promišljeno i dosljedno, koristi se akumuliraju.
Čitljivost i razumijevanje koda
Jedan od najvidljivijih efekata refaktorisanja je taj što kod postaje mnogo lakši za čitanje . Kratke, jasne funkcije, izražajna imena i jednostavne strukture omogućavaju svakom programeru (čak i onom koji je nov u projektu) da razumije šta se dešava bez potrebe da dešifruje zagonetke.
Dobra čitljivost ne samo da poboljšava produktivnost, već i olakšava timski rad i preglede koda , smanjuje nesporazume i pomaže da dizajnerske odluke budu očiglednije na prvi pogled.
Smanjenje nepotrebne složenosti
Vremenom, softver obično akumulira posebne uslove, brze zakrpe i alternativna rješenja , povećavajući ciklomatsku složenost. Refaktorisanje ima za cilj smanjenje ove vještačke složenosti, zadržavajući samo minimum potreban za rješavanje problema.
Podjela ogromnih funkcija, izbjegavanje dubokog ugniježđivanja i primjena odgovarajućih dizajnerskih obrazaca čini sistem predvidljivijim i manje sklonim suptilnim greškama , jer se logika razumije na prvi pogled, umjesto da zahtijeva arheološka istraživanja.
Jednostavnost održavanja i proširenja
U praksi, većina budžeta projekta ide na održavanje: ispravljanje grešaka, prilagođavanje sistema i dodavanje novih funkcija . Dobro refaktorisan kod omogućava da se ove promjene izvrše uz manje napora i manji rizik od kvara nečega što je radilo.
Kada je kodna baza fleksibilna i organizirana, uvođenje novih funkcija ne zahtijeva prepisivanje pola modula ; često je dovoljno dodati novu klasu ili proširiti postojeće ponašanje prateći jasnu strukturu.
Sprečavanje grešaka i smanjenje broja bugova
Iako samo refaktorisanje ne garantuje kod bez grešaka, jednostavniji i konzistentniji kod obično ima manje grešaka . Eliminisanjem redundancija, smanjenjem složenih uslovnih izraza i razjašnjavanjem odgovornosti, potencijal za logičke greške se minimizira.
Nadalje, razumljiviji sistem omogućava ranije otkrivanje i brže ispravljanje grešaka , budući da je lociranje pravog uzroka kvara mnogo lakše kada struktura nije haotična.
Smanjenje tehničkog duga
Tehnički dug nastaje kad god se odabere brzo rješenje za koje znamo da nije idealno , obično kako bi se ispoštovali rokovi ili riješila hitna greška. Ovaj "dug" se plaća kasnije, kada bilo koja promjena oduzima više vremena i nosi veći rizik.
Kontinuirano refaktorisanje djeluje kao mehanizam za postepenu otplatu tog duga , čisteći ono što je prethodno brzopleto implementirano. Na taj način, umjesto da projekat postaje sve krhkiji tokom godina, on dobija na robusnosti i prilagodljivosti.
Principi i najbolje prakse prilikom refaktorisanja
Da bi refaktorisanje bilo zaista efikasno, nije dovoljno jednostavno "popravljati stvari u hodu". Važno je slijediti određene principe i navike koji drže proces pod kontrolom i smanjuju rizike.
Održavanje netaknute funkcionalnosti
Zlatno pravilo refaktorisanja je da se vidljivo ponašanje sistema ne mijenja . Ako nakon refaktorisanja aplikacija radi nešto drugačije, mi ne refaktorišemo; mi modificiramo funkcionalnost (što može biti neophodno, ali to je druga priča).
Zato je toliko važno oslanjati se na automatizirano testiranje i male korake. Svaka promjena treba biti odmah provjerljiva kako bi se osiguralo da ništa nije narušilo ono što je već funkcioniralo.
Kontinuirano refaktorisanje u odnosu na jednokratno refaktorisanje
Postoje dva glavna načina pristupa refaktorisanju: kao svakodnevna navika integrirana u vaš rad ili kao veće, jednokratne akcije. Najrazumniji pristup je obično kombinacija oba.
U pristupu kontinuiranog poboljšanja, programeri prave mala poboljšanja čim ih otkriju : preimenovanje zbunjujuće metode, uklanjanje ponovljene funkcije, pojednostavljenje predugog if izraza... To je način razmišljanja "ostaviti kod malo boljim nego što ste ga zatekli".
U ciljanom pristupu, šira refaktorisanja se planiraju za posebno problematična područja , kao što je kritični modul s mnogo grešaka ili ključna komponenta čija je složenost naglo porasla. Ovaj pristup obično uključuje više analize i koordinacije jer promjene mogu imati veći utjecaj.
Veza između refaktorisanja i TDD-a (razvoj vođen testiranjem)
Refaktorisanje i razvoj vođen testiranjem (TDD) prirodno idu ruku pod ruku . U TDD-u, klasični ciklus je prvo napisati test koji ne uspije (crveno), implementirati minimalni kod potreban za njegov prolaz (zeleno), a zatim refaktorisati taj kod dok testovi ostaju zeleni.
Ovaj pristup se može sažeti u crveno-zelenom obrascu refaktorisanja : testiranje pruža potrebno samopouzdanje da se usudimo poboljšati dizajn bez stalnog straha od kvara. Bez dobre testne mreže, refaktorisanje postaje nezgrapno i rizično, jer svaka promjena može uvesti tihe greške.
Alati i tehnike koji olakšavaju refaktorisanje
Danas, većina integriranih razvojnih okruženja (IDE) uključuje moćne alate za refaktorisanje : preimenovanje simbola u cijelom projektu, izdvajanje metoda, premještanje klasa između paketa, uvođenje varijabli, invertovanje uvjetnih izraza itd., sve uz garanciju da su reference ispravno ažurirane.
Pored IDE-ova, alati za statičku analizu koda poput SonarQube-a, ESLint-a i sličnih alata pomažu u otkrivanju mirisa koda, nekonzistentnih stilova ili opasnih obrazaca prije nego što uopće dođu do produkcije. Platforme za saradnju zasnovane na Gitu (GitHub, GitLab, itd.) omogućavaju vam da pregledate ove promjene pomoću zahtjeva za povlačenje/spajanje kako biste osigurali da refaktorisanje ima smisla.
Praktičan proces refaktorisanja korak po korak
Pored teorije, važno je razumjeti kako pristupiti refaktorisanju u praksi bez predumišljaja. Praćenje niza razumnih koraka uveliko pomaže u održavanju kontrole.
1. Identifikujte problematična područja u kodu
Prvi korak je identificirati u koje dijelove sistema vrijedi uložiti trud. Mirisi koda služe kao početni vodič : duplicirani kod, vrlo duge metode, klase koje rade sve, glomazne uvjetne strukture, pretjerano spajanje itd.
Druga potencijalna područja za refaktorisanje uključuju ponavljajuće greške, module kojima uvijek treba dugo vremena da se naprave promjene ili dijelove koda koje svi izbjegavaju jer "uvijek nešto krene po zlu". Ovo su jasni kandidati za dobro osmišljeno refaktorisanje.
2. Analizirajte utjecaj i planirajte promjene
Prije bilo kakvih promjena, važno je razumjeti obim refaktorisanja : koji dijelovi sistema zavise od tog koda, koji rizici postoje i koje strategije ublažavanja se mogu primijeniti. Podešavanje izolovane funkcije nije isto što i modifikacija osnovnog poslovanja.
U ovoj fazi se odlučuje da li će se refaktorisanje vršiti postepeno u nekoliko iteracija ili u većem bloku, koji su testovi neophodni i koje međuprocese je moguće završiti kako bi se izbjeglo da sistem ostane u nestabilnom stanju.
3. Kreirajte ili ojačajte testove prije refaktorisanja
Jedno je jasno: refaktorisanje bez testova je kao igranje ruskog ruleta . Prije nego što počnete s eksperimentisanjem, morate se uvjeriti da imate razumnu sigurnosnu mrežu: jedinične testove, integracijske testove ili čak testove karakterizacije koji dokumentuju trenutno ponašanje.
U naslijeđenom kodu bez testova, jedna od opcija je korištenje tehnika poput Golden Mastera : hvatanje trenutnih ulaza i izlaza kako bi se provjerilo da li se sve nastavlja ponašati na isti način nakon promjena. Pasivni testovi ili pristup prvog pisanja jednostavnih testova koji definiraju uočljivo ponašanje također su korisni.
4. Dekomponujte i pojednostavite funkcije i klase
Kada steknete sigurnost u pogledu ispravnosti provjere, možete početi s nečim vrlo isplativim: razbijanjem dugih metoda i prevelikih klasa na manje jedinice s jasnijim odgovornostima. Često samo ovo uveliko poboljšava jasnoću.
Cilj je da svaka funkcija obavlja jedan, dobro definiran zadatak, a da klase ne budu monstruozne, miješajući poslovnu logiku, pristup podacima i prezentaciju . Izdvajanjem dijelova pojavljuju se i mogućnosti ponovne upotrebe, a smanjuje se dupliranje.
5. Preimenuj radi jasnoće
Dok reorganizujete dijelove, dobro je vrijeme da prilagodite nazive metoda, varijabli i klasa kako bi bolje odražavali njihove stvarne odgovornosti. Dobro ime je gotovo samo po sebi dokumentacija.
Ključno je to što su prilikom čitanja koda "šta" i "zašto" očigledni bez potrebe za pretraživanjem desetina redova. Ovo također smanjuje potrebu za suvišnim komentarima i minimizira pogrešna tumačenja.
6. Eliminišite mrtav i suvišan kod
Još jedan bitan dio procesa je otkrivanje i čišćenje koda koji se više ne koristi ili je postao zastario : funkcije bez referenci, zastavice koje niko ne gleda, grane koje je nemoguće izvršiti itd. Sva ta buka dodaje složenost bez pružanja vrijednosti.
Također je vrijeme da se duplicirana ponašanja objedine na jednom mjestu, zamjenjujući kopirana i zalijepljena ponašanja pozivima zajedničke metode ili novim apstrakcijama koje bolje predstavljaju problemsku domenu.
7. Pokrenite testove nakon svake male promjene
Tokom refaktorisanja, testove treba pokretati nakon svakog značajnog koraka kako bi se osiguralo da sve i dalje funkcioniše . Cilj je izbjeći akumuliranje velikih promjena bez verifikacije, tako da se svi kvarovi mogu lako pripisati određenoj promjeni.
Ovaj provjereni pristup mikrokoraka osigurava nesmetan rad sistema u svakom trenutku i izbjegava situacije u kojima se nešto pokvari, a onda je vrlo teško znati šta je uzrokovalo problem , jer su se usput dogodile mnoge modifikacije.
Alati i podrška za sigurno refaktorisanje
Ručno refaktorisanje, mijenjanje referenci jednu po jednu, danas je besmisleno. Moderna IDE okruženja su dizajnirana upravo da automatizuju mehanički dio refaktorisanja i minimiziraju glupe greške.
IDE sa ugrađenom podrškom za refaktorisanje
Okruženja poput IntelliJ IDEA, Visual Studio ili Eclipse nude inteligentne operacije refaktorisanja : preimenovanje simbola u cijelom projektu, izdvajanje metoda i varijabli, premještanje klasa između paketa, uvođenje interfejsa, promjenu potpisa metoda i još mnogo toga.
Ovi alati analiziraju sintaksno stablo koda i dosljedno ažuriraju sve reference , štedeći vas od ručnih pretraga i zamjena sklonih greškama. Ovo podstiče češće refaktorisanje jer se mehanički troškovi značajno smanjuju.
Dodaci, ekstenzije i linteri
Ako koristite editore poput Visual Studio Code-a, možete proširiti njihove mogućnosti refaktorisanja pomoću dodataka specifičnih za jezik . Ekstenzije poput "Abracadabra" ili paketi za refaktorisanje za PHP, JavaScript itd. dodaju naredbe koje automatizuju uobičajene transformacije.
Nadalje, linteri i statički analizatori poput ESLinta, SonarQubea ili ekvivalentni alati za druge jezike ukazuju na duplikacije, prekomjernu složenost, neugodne mirise i kršenja standarda, što su savršene početne tačke za dobar refaktoring.
Platforme za kontrolu verzija i timski rad
Kada se refaktorisanje radi kao tim, bitno je koristiti platforme za kontrolu verzija poput GitHub-a ili GitLab-a . Tamo možete kreirati specifične grane za refaktorisanje, otvarati zahtjeve za spajanje/povlačenje i tražiti recenzije od drugih programera.
Ovaj tok rada omogućava da se promjene dizajna razmatraju, validiraju i integriraju na kontroliran način , s jasnom historijom i mogućnošću vraćanja na prethodno stanje ako nešto pođe po zlu. Refaktoriranje prestaje biti nasumična operacija i postaje dio redovnog razvojnog ciklusa.
Refaktorisanje naslijeđenog koda i stvaranje sigurnosne mreže
Veliki dio stvarnog rada programera uključuje modificiranje naslijeđenog koda koji nisu sami napisali . U ovom scenariju, refaktoriranje je ključni alat za razvoj sistema bez izazivanja njegovog potpunog raspada.
Kada se suočite s netestiranim naslijeđenim kodom, u osnovi postoje dva puta: promijeniti ga i ukrstiti palčeve ili prvo izgraditi minimalnu sigurnosnu mrežu s testovima, a zatim započeti s refaktoriranjem. Očigledno je da je druga opcija preporučena ako želite mir.
Dilema je u tome što, da biste napisali ove testove, ponekad morate malo izmijeniti postojeći kod (na primjer, uvesti zavisnosti ili odvojiti odgovornosti). To stvara neku vrstu začaranog kruga: potrebni su mi testovi da bih promijenio kod, ali moram promijeniti kod da bih ga mogao testirati.
Da bi se prekinuo ovaj ciklus, koriste se tehnike poput Golden Mastera ili testiranja odobrenja , koje omogućavaju hvatanje trenutnog ponašanja i osiguravanje da se ono ne promijeni tokom refaktorisanja. Karakterizacijsko testiranje također pomaže, dokumentirajući kako se sistem zapravo ponaša danas, čak i ako je dizajn užasan.
U osjetljivim okruženjima, uobičajena je praksa jačanje sigurnosti parnim programiranjem , gdje dvije osobe zajedno pregledaju stari kod dok istovremeno unose promjene. Baš kao i u složenoj hirurgiji, nije dobra ideja raditi samostalno kada je rizik od oštećenja nečeg važnog visok.
Konceptualni primjer tehnika refaktorisanja
Da bismo ovo ilustrirali, zamislite klasu "Kalkulator" s ogromnom metodom koja izvršava nekoliko operacija, ispisuje rezultate, kombinira proračune i obrađuje greške. Čak i ako radi, postoji nekoliko nedostataka koda: predugačka metoda, pomješane odgovornosti i loša ponovna upotreba.
Razuman pristup refaktorisanju bi uključivao izdvajanje svake operacije u njenu vlastitu metodu (sabiranje, oduzimanje, množenje, dijeljenje), ostavljajući glavnoj metodi da jednostavno orkestrira pozive i prikazuje rezultate. Odvajanjem komponenti, klasa postaje čitljivija, a testiranje svake operacije pojedinačno je trivijalno.
Odatle biste mogli nastaviti: preimenovanjem klase ili metoda kako biste ih učinili izražajnijima , izoliranjem logike prezentacije (ispisa) od logike izračuna, uvođenjem jasnijeg rukovanja greškama kao što je dijeljenje nulom itd. Svaki korak zadržava ponašanje, ali dizajn dobija na jasnoći i budućoj proširivosti.
Ovaj primjer sažima ono što se stalno dešava u stvarnim projektima: nije potrebno prepisivati sve od nule , već primijeniti male tehnike refaktorisanja na kod koji već imamo kako bismo ga postepeno približili zdravijem dizajnu.
S obzirom na sve navedeno, postaje jasnije zašto refaktorisanje nije luksuz, već neophodnost za svaki projekat koji želi da živi dugi niz godina: održavanje koda organizovanim, čitljivim i fleksibilnim štedi vrijeme , čini buduće promjene bržim i sigurnijim, smanjuje akumulirani tehnički dug i omogućava timovima da sarađuju bez straha na kodnoj bazi koja, umjesto da trune, poboljšava se sa svakom iteracijom.
Strastveni pisac o svijetu bajtova i tehnologije općenito. Volim dijeliti svoje znanje kroz pisanje, a to je ono što ću raditi na ovom blogu, pokazivati vam sve najzanimljivije stvari o gadžetima, softveru, hardveru, tehnološkim trendovima i još mnogo toga. Moj cilj je pomoći vam da se krećete u digitalnom svijetu na jednostavan i zabavan način.
