Dio 1 – Klasifikacija, mjerljivost
Dio 2 – Taktike i redizajn
Dopunska praksa – Mjerenje i keš
Materijale priredio Erkan Islamović
erkan.islamovic@eubd.edu.ba · erkan.islamovic@gmail.com
Deset predavanja: dva časa teorije i jedan čas dopunske prakse. Danas je poglavlje 6. Isti primjer kroz knjigu: DeliveryApp 2.0.
| Pred. | Dio 1 | Dio 2 | Praksa |
|---|---|---|---|
| 1 | Projekat i proizvod, trendovi, etika | Inženjerski pristup, alati, automatizacija | Repozitorij i vizija proizvoda |
| 2 | Modeli, uloge, planiranje | Rizici, tim, kvalitet, poboljšanje procesa | Plan izdanja, registar rizika |
| 3 | Konceptualni model, UML, SOLID | Prototip, UX, specifikacija dizajna | Wireframe i SDD |
| 4 | IDE, organizacija koda, OOP, okviri | Podaci, MVC/MVVM, čisti kod, refaktoring | Refaktoring funkcije |
| 5 | Git, pull request, CI | Testovi, CD, kontejneri | GitHub Actions |
Deset predavanja: dva časa teorije i jedan čas dopunske prakse. Danas: poglavlje 6 (označeno). Isti primjer kroz knjigu: DeliveryApp 2.0.
| Pred. | Dio 1 | Dio 2 | Praksa |
|---|---|---|---|
| 6 | Klasifikacija, mjerljivost | Taktike i redizajn | Mjerenje i keš |
| 7 | Odluke, pogledi, stilovi | Troslojna i čista arhitektura, predlošci | ADR i C4 |
| 8 | CBSE, odlike, interfejsi | Principi, smjernice, provođenje | Paket sa verzijom |
| 9 | SaaS, SOA, IoT, proizvodne linije | Aspekti, reaktivno programiranje | Dekorator i tok događaja |
| 10 | Vrijednost, troškovi, razvoj ili kupnja, TCO | Metrike, procjena, NPV, povrat | NPV u Pythonu |
U julu 2016. firma Niantic pustila je igru Pokémon GO: igrači hodaju po stvarnom gradu i na ekranu mobitela hvataju čudovišta. Igra je prvo puštena u Australiji i Novom Zelandu, i u roku od petnaest minuta promet je prešao sve procjene. Niantic je planirao kapacitet za najgori slučaj od pet puta više igrača nego što je procijenio. Stvarni promet bio je oko pedeset puta veći od procjene. Igra je, funkcionalno, radila savršeno: čudovišta su se pojavljivala, lopte letjele, bodovi se brojali. Ali igrači satima nisu mogli ni ući u nju, jer su serveri bili zagušeni.
Inženjeri Niantica i Googlea, čiji je oblak igra koristila, danima su dodavali kapacitet i mijenjali dijelove sistema, i tek tada je igra mogla biti puštena u Japanu i Evropi. Lekcija je stara koliko i softver, ali Pokémon GO ju je ispričao milionima ljudi: igra koja ne može da se otvori ne radi, bez obzira na to koliko su dobro napisana pravila.
U poglavlju 5 naučili smo kako izmjena brzo i bez straha stiže do korisnika. Ali korisnik ne ocjenjuje samo šta proizvod radi, nego i kako: da li je brz, da li je stalno dostupan, da li čuva podatke, da li ga je lako koristiti. To su nefunkcionalni zahtjevi. Prvi dio govori šta su, kako se klasifikuju i kako se zapisuju tako da se mogu izmjeriti. Drugi dio govori kako se implementiraju: keš, skaliranje, redovi poruka, otpornost na kvarove, i kako se DeliveryApp 2.0 redizajnira da izdrži ručak u tri grada.
Nakon poglavlja možete:
objasniti razliku između funkcionalnih i nefunkcionalnih zahtjeva i zašto NFR mogu „oboriti” funkcionalnost; nabrojati karakteristike kvaliteta po ISO/IEC 25010; klasifikovati NFR prema tome gdje se implementiraju; zapisati NFR kao mjerljiv scenarij; izračunati dozvoljeni zastoj iz procenta dostupnosti; objasniti taktike za performanse, skalabilnost, dostupnost i otpornost; izmjeriti efekat keša; predložiti redizajn proizvoda za novi NFR.
| Čas | Sadržaj | Na času |
|---|---|---|
| Teorija 1 | 6.1–6.4 Šta su NFR, ISO 25010, klasifikacija, mjerljivi scenariji | Prepiši „brzo” u scenarij; tabela devetki |
| Teorija 2 | 6.5–6.8 Performanse, dostupnost, ostali kvaliteti, redizajn | Od 200 do 600 korisnika: šta mijenjamo? |
| Dopunska praksa | Mjerenje odziva s kešom i bez keša | 10 s naspram 0,05 s |
Funkcionalni zahtjev kaže šta sistem radi: „Kupac može ponoviti prošlu narudžbu.” Nefunkcionalni zahtjev kaže kako to radi: „Ponovljena narudžba se prikaže za najviše 2 sekunde, i u vrijeme ručka.”
Analogija s automobilom: funkcionalno, automobil vozi, koči i skreće. Nefunkcionalno, troši 5 litara na sto kilometara, ima pet zvjezdica za sigurnost, pali se i na −20 °C i servisira se svakih 15.000 km. Automobil koji vozi, ali ne pali po hladnoći, za vlasnika na sjeveru jednostavno ne radi.
Zato kažemo da NFR mogu oboriti funkcionalnost. Pokémon GO je imao sve funkcije, ali bez skalabilnosti igrači nisu mogli ništa. DeliveryApp s tačnim obračunom dostave, ali sa stranicom koja se učitava deset sekundi u podne, gubi kupce koji odu telefonom naručiti direktno od restorana.
NFR su teži od funkcionalnih zahtjeva iz tri razloga:
Da bi se o kvalitetu razgovaralo istim riječima, međunarodni standard ISO/IEC 25010 dijeli kvalitet softverskog proizvoda u karakteristike. Izdanje iz 2011. ima osam karakteristika; revizija iz 2023. dodala je sigurnost u smislu bezbjednosti (safety, da softver ne ugrozi ljude i okolinu) i preimenovala dvije postojeće.
| Karakteristika | Pitanje | NFR DeliveryApp |
|---|---|---|
| Funkcionalna prikladnost | radi li tačno ono što treba? | dostava tačna na cent |
| Efikasnost performansi | koliko brzo i s koliko resursa? | NZ-1a: 95 % odgovora ≤ 2 s pri 600 korisnika |
| Kompatibilnost | radi li s drugim sistemima? | sistem plaćanja, servis mapa |
| Upotrebljivost (2023: sposobnost interakcije) | lako se koristi? pristupačno? | NZ-4: prva narudžba ≤ 3 min; kontrast ≥ 4,5 : 1 |
| Pouzdanost | radi li stalno, oporavlja li se? | NZ-2: dostupnost 99,5 % |
| Sigurnost (zaštita) | jesu li podaci zaštićeni? | NZ-3: heš lozinke, 2FA za restoran |
| Održivost | lako se mijenja i testira? | NZ-7: novi grad za 1 dan, bez novog koda |
| Prenosivost (2023: fleksibilnost) | radi li u drugom okruženju? | kontejner radi kod bilo kojeg pružaoca oblaka |
| Bezbjednost (safety, od 2023) | može li ugroziti ljude? | dostavljač ne dobija poruke dok vozi |

Standard ISO/IEC 25010 je dio porodice SQuaRE (Systems and software Quality Requirements and Evaluation). Uz model kvaliteta proizvoda ima i model kvaliteta u upotrebi: koliko je korisnik efikasan, zadovoljan i bezbjedan kad koristi proizvod u stvarnom životu.
Programeru je važno i drugo pitanje: gdje se NFR implementira? Odgovor određuje ko ga radi i koliko košta.
| Vrsta | Gdje se implementira | Primjeri u DeliveryApp 2.0 |
|---|---|---|
| Arhitekturalni | u strukturi sistema; teško se mijenja kasnije | skalabilnost (više servera), dostupnost (redundancija), izolacija gradova (NZ-6) |
| Lokalni (u kodu) | u jednoj komponenti ili funkciji | heš lozinke (NZ-3), provjera unosa, kontrast boja (NZ-4) |
| Procesni | u načinu rada tima | održivost: CI, testovi, pregled koda; brzina isporuke |
| Operativni | u radu sistema u produkciji | nadzor, logovi, rezervne kopije, brisanje starih podataka (NZ-5) |
| Ograničenja | nametnuti spolja, ne biraju se | zakon o zaštiti ličnih podataka, fiskalizacija, obavezni jezik |
Sommerville predlaže i podjelu po porijeklu: proizvodni NFR (ponašanje proizvoda: brzina, pouzdanost), organizacioni (pravila firme: jezik, alati, proces) i vanjski (zakoni, etika, regulatori).
Praktična posljedica: arhitekturalni NFR moraju biti poznati rano, prije nego što se arhitektura izabere (poglavlje 7). Lokalni se mogu dodati u bilo kojem sprintu. Zato Lana i Amar prvo pitaju za broj korisnika i dostupnost, a tek poslije za boju dugmeta.
„Sistem mora biti brz” nije zahtjev, nego želja: niko ne može provjeriti da li je ispunjena. NFR mora biti mjerljiv. Bass, Clements i Kazman predlažu scenarij kvaliteta sa šest dijelova:
| Dio | Pitanje | Primjer: ručak u tri grada |
|---|---|---|
| izvor | ko ili šta izaziva događaj? | kupci u gradovima A, B i C |
| podsticaj | šta se desi? | 600 istovremenih korisnika pregleda jelovnike i naručuje |
| okruženje | u kojim uslovima? | normalan rad, radni dan 12–14 h |
| artefakt | koji dio sistema? | cijeli DeliveryApp 2.0 |
| odgovor | šta sistem radi? | prikaže jelovnik i primi narudžbu |
| mjera | kako mjerimo? | 95 % odgovora za najviše 2 s (p95 ≤ 2 s) |
Zašto p95, a ne prosjek? Prosjek sakriva loše slučajeve. Ako 90 zahtjeva traje 0,5 s, a 10 zahtjeva 15 s, prosjek je 1,95 s, „ispod 2 sekunde”, ali svaki deseti kupac čeka petnaest sekundi i odlazi. Percentil p95 kaže: 95 % zahtjeva je brže od ove vrijednosti.
Devetke dostupnosti. Dostupnost se piše u procentima, a lakše se razumije kao dozvoljeni zastoj. Za mjesec od 30 dana (720 sati):
| Dostupnost | Zastoj mjesečno | Šta to znači |
|---|---|---|
| 99 % | 7,2 sata | jedan radni dan |
| 99,5 % (NZ-2) | 3,6 sati | jedno popodne |
| 99,9 % | 43,2 minute | jedna pauza za kafu |
| 99,99 % | oko 4,3 minute | jedna pjesma |
Svaka nova devetka obično znači više servera, više automatizacije i više novca. Zato se pita: koliko košta sat zastoja DeliveryApp u podne? Ako je odgovor „mnogo manje nego treći server”, 99,5 % je pravi izbor.
Prepišite kao mjerljiv scenarij: „Aplikacija treba biti sigurna” i „Lako se dodaje novi grad”.
Odgovori: tipka R ili klik na zamućeno polje.
Performanse govore koliko je sistem brz za jednog korisnika; skalabilnost govori da li ostaje brz kad korisnika bude deset puta više. Za DeliveryApp 2.0 važno je oboje: verzija 1.x zadovoljava NZ-1 (200 korisnika), a 2.0 mora izdržati 600.
Taktike za performanse i skalabilnost:

Mjeri, ne nagađaj. Prije bilo koje taktike, izmjeri gdje se vrijeme troši. U dopunskoj praksi mjerimo jelovnik koji se čita iz simulirane baze (50 ms po čitanju). Na računaru autora rezultat je:
bez keša : prosjek 50.457 ms, p95 50.859 ms, 200 zahtjeva za 10.09 s
s kešom : prosjek 0.252 ms, p95 0.000 ms, 200 zahtjeva za 0.05 sS kešom samo prvi zahtjev ide u bazu (50 ms), a ostalih 199 traje manje od hiljaditog dijela milisekunde. Zato je prosjek 0,25 ms (50 ms podijeljeno na 200 zahtjeva), a p95 praktično nula. Brojevi se razlikuju od računara do računara, ali odnos ostaje: oko dvjesto puta brže.
„Ako je sporo, kupićemo jači server.” Jači server pomaže dok ne dođete do njegove granice, a kod koji za listu od 100 narudžbi pravi 101 upit (problem N + 1 iz poglavlja 4) biće spor i na najjačem serveru. Prvo se mjeri, pa popravlja uzrok, pa tek onda skalira.
Dostupnost je procenat vremena u kojem sistem radi; otpornost je sposobnost da radi i kad nešto pukne. U sistemu s mnogo dijelova, nešto uvijek puca: server se restartuje, mreža zakašnjava, servis mapa ne odgovara. Pitanje nije „hoće li”, nego „šta onda”.
Taktike:

Netflix je 2011. opisao alat Chaos Monkey, koji u radnom vremenu namjerno gasi slučajno izabrane servere u njihovoj produkciji. Ideja je da inženjeri moraju graditi sistem koji preživi gubitak bilo kojeg servera, jer znaju da će se to sigurno desiti, i to danju, kad su svi na poslu, a ne u tri ujutro.
Ostali NFR DeliveryApp 2.0 i kako se implementiraju:
| NFR | Vrsta | Implementacija |
|---|---|---|
| NZ-3 lozinke kao heš, 2FA za restoran | lokalni | biblioteka za heširanje (npr. bcrypt, Argon2); drugi faktor (aplikacija ili SMS) |
| NZ-4 prva narudžba ≤ 3 min, kontrast | lokalni + procesni | test upotrebljivosti s 5 korisnika; automatska provjera kontrasta u CI-ju |
| NZ-5 brisanje adrese i telefona nakon 12 mjeseci | operativni | noćni posao koji briše stare lične podatke; izvještaj o broju obrisanih |
| NZ-6 izolacija gradova | arhitekturalni | svaki red u bazi ima oznaku grada (zakupca); svaki upit filtrira po gradu; test koji to provjerava |
| NZ-7 novi grad za 1 dan, bez novog koda | arhitekturalni + održivost | tarifa kao podatak (poglavlje 3); skripta za uključivanje novog grada |
| održivost | procesni | CI, testovi, pregled koda, složenost ≤ 10 (poglavlja 4–5) |
Princip najmanjih prava važi za sigurnost: dostavljač vidi samo adresu narudžbe koju vozi, a ne istoriju kupca; servis obavještenja može čitati telefon, ali ne i plaćanja. Privatnost se ugrađuje u dizajn od početka (privacy by design), a ne dodaje na kraju.
Kad se NFR promijene, nekad nije dovoljno „podesiti” sistem; treba ga redizajnirati. DeliveryApp 1.x je napravljen za jedan grad i 200 korisnika: jedna aplikacija na jednom serveru, jedna baza, SMS se šalje odmah dok kupac čeka. Za DeliveryApp 2.0 važi NZ-1a (600 korisnika), NZ-6 i NZ-7.
Tim radi redizajn u četiri koraka:
| DeliveryApp 1.x | DeliveryApp 2.0 | |
|---|---|---|
| aplikacija | jedan server | dvije ili više instanci iza raspoređivača |
| jelovnik | čita se iz baze svaki put | keš, poništava se kad restoran promijeni cijenu |
| obavještenja | SMS dok kupac čeka | red poruka, poseban servis |
| baza | jedna | glavna + replika za čitanje; oznaka grada u svakoj tabeli |
| pravila dostave | u kodu | tarifa grada kao podatak |
| nadzor | logovi na serveru | grafikoni p95, grešaka i dostupnosti; upozorenja |

Primijetite da se funkcionalni zahtjevi u ovoj tabeli skoro nisu promijenili: kupac i dalje naručuje, plaća i prati narudžbu. Promijenili su se NFR, i to je bilo dovoljno da se promijeni pola arhitekture. O tome kako se takve odluke zapisuju govori poglavlje 7.
Odgovori: tipka R ili klik na zamućeno polje.
Cilj je izmjeriti efekat keša i napisati jedan mjerljiv scenarij. Trajanje: jedan čas.
Pokrenite primjeri/python/kes.py. Program 200 puta čita jelovnik iz simulirane baze (50 ms po čitanju), pa isto to s kešom (functools.lru_cache), i ispisuje prosjek, p95 i ukupno vrijeme.
python primjeri/python/kes.pyZapišite svoje rezultate. Zašto je prosjek s kešom oko 0,25 ms, a ne nula?
Dodajte u program promjenu jelovnika (npr. novo jelo) poslije prvog čitanja. Šta vraća verzija s kešom? Pozovite jelovnik_s_kesom.cache_clear() nakon promjene i provjerite ponovo. Zapišite jednom rečenicom kada DeliveryApp mora poništiti keš.
Postavite KASNJENJE_BAZE = 0.005 (5 ms) i ponovite mjerenje. Da li se keš i dalje isplati? Šta to govori o pravilu „prvo izmjeri”?
U repozitoriju deliveryapp-2 napravite docs/nfr.md i upišite dva scenarija u tabeli sa šest dijelova (izvor, podsticaj, okruženje, artefakt, odgovor, mjera): jedan za performanse (NZ-1a), jedan za izolaciju gradova (NZ-6).
Rezultat: izmjereni rezultati za 50 ms i 5 ms, odgovor o poništavanju keša i docs/nfr.md s dva scenarija.
Rješenja su sakrivena – tipka R ili klik na okvir.
Razvrstajte: a) kupac može platiti karticom; b) plaćanje se završi za najviše 5 sekundi; c) podaci kartice se ne čuvaju u bazi DeliveryApp; d) restoran može označiti jelo kao rasprodato; e) aplikacija radi na Androidu od verzije 10 i iOS-u od verzije 15.
a) funkcionalni; b) nefunkcionalni – performanse; c) nefunkcionalni – sigurnost (i ograničenje zbog pravila kartičnih kuća); d) funkcionalni; e) nefunkcionalni – kompatibilnost/prenosivost.
Udruženje traži dostupnost 99,95 % mjesečno (30 dana). Koliko je dozvoljeno zastoja? Šta biste pitali prije nego što prihvatite?
720 h × 0,0005 = 0,36 h ≈ 21,6 minuta mjesečno. Pitao bih koliko košta sat zastoja (izgubljene narudžbe), da li zastoj noću (kad nema narudžbi) uopšte smeta, i koliko udruženje može platiti za redundanciju koju takva dostupnost traži. Moguće je da je 99,5 % u vrijeme rada restorana pravi zahtjev.
Zahtjev glasi: „DeliveryApp mora brzo prihvatati restorane iz novih gradova.” Napišite ga kao scenarij kvaliteta.
Izvor: administrator DeliveryApp. Podsticaj: zahtjev za uključivanje novog grada s 10 restorana i tarifom. Okruženje: normalan rad, proizvod u produkciji. Artefakt: podešavanja i baza DeliveryApp 2.0. Odgovor: grad je dostupan kupcima s tačnim cijenama, bez izmjene koda i nove isporuke. Mjera: najviše 1 radni dan, 0 linija novog koda, svi testovi tarife prolaze.
Za svaki problem predložite taktiku: a) stranica jelovnika je spora jer se svaki put čita iz baze; b) kupac čeka 4 s dok se šalje SMS; c) servis mapa povremeno ne odgovori po 30 sekundi; d) jedan server je pao i DeliveryApp nije radio sat vremena.
a) keš s poništavanjem pri promjeni; b) red poruka i asinhrono slanje; c) vremensko ograničenje od 2 s, ponovni pokušaj s pauzom, prekidač kola i gracilna degradacija (posljednja poznata udaljenost ili ručna potvrda adrese); d) redundancija: bar dvije instance iza raspoređivača opterećenja i nadzor s upozorenjem.