Razvoj programskih proizvoda · Poglavlje 8 · Predavanje 8

Arhitektura temeljena na komponentama

Dio 1 – CBSE, odlike, interfejsi

Dio 2 – Principi, smjernice, provođenje

Dopunska praksa – Paket sa verzijom

Materijale priredio Erkan Islamović

erkan.islamovic@eubd.edu.ba · erkan.islamovic@gmail.com

Šta učimo ovog semestra (1–5)

Deset predavanja: dva časa teorije i jedan čas dopunske prakse. Danas je poglavlje 8. Isti primjer kroz knjigu: DeliveryApp 2.0.

Pred.Dio 1Dio 2Praksa
1Projekat i proizvod, trendovi, etikaInženjerski pristup, alati, automatizacijaRepozitorij i vizija proizvoda
2Modeli, uloge, planiranjeRizici, tim, kvalitet, poboljšanje procesaPlan izdanja, registar rizika
3Konceptualni model, UML, SOLIDPrototip, UX, specifikacija dizajnaWireframe i SDD
4IDE, organizacija koda, OOP, okviriPodaci, MVC/MVVM, čisti kod, refaktoringRefaktoring funkcije
5Git, pull request, CITestovi, CD, kontejneriGitHub Actions
DeliveryApp 2.0 · narudžba N-1001 · 24,50 €

Šta učimo ovog semestra (6–10)

Deset predavanja: dva časa teorije i jedan čas dopunske prakse. Danas: poglavlje 8 (označeno). Isti primjer kroz knjigu: DeliveryApp 2.0.

Pred.Dio 1Dio 2Praksa
6Klasifikacija, mjerljivostTaktike i redizajnMjerenje i keš
7Odluke, pogledi, stiloviTroslojna i čista arhitektura, predlošciADR i C4
8CBSE, odlike, interfejsiPrincipi, smjernice, provođenjePaket sa verzijom
9SaaS, SOA, IoT, proizvodne linijeAspekti, reaktivno programiranjeDekorator i tok događaja
10Vrijednost, troškovi, razvoj ili kupnja, TCOMetrike, procjena, NPV, povratNPV u Pythonu
DeliveryApp 2.0 · narudžba N-1001 · 24,50 €

Priča za početak

Priča za početak

Na istoj konferenciji u Garmischu 1968. godine, o kojoj smo čitali u poglavlju 1, programer Douglas McIlroy iz Bell Labsa održao je izlaganje pod naslovom „Masovno proizvedene softverske komponente”. Pitao je zašto softverska industrija nema ono što ima svaka druga industrija: katalog standardnih dijelova. Proizvođač automobila ne pravi sam svaki vijak; kupi ga, po standardu, iz kataloga. McIlroy je zamišljao da će programeri birati gotove rutine iz porodica, prema preciznosti, robusnosti i brzini, i od njih sklapati programe. Skoro pola vijeka kasnije, 22. marta 2016, ta vizija se ostvarila na način koji niko nije očekivao.

Priča za početak

Priča za početak

Programer Azer Koçulu povukao je sve svoje pakete iz registra npm, u kojem programeri JavaScripta dijele komponente. Među njima je bio i left-pad, funkcija od jedanaest redova koja dopunjava tekst razmacima s lijeve strane. Ispostavilo se da od nje, preko lanca drugih paketa, zavise popularni alati, i gradnja hiljada projekata širom svijeta odjednom je počela padati. Registar je paket vratio za nekoliko sati i promijenio pravila povlačenja. Katalog dijelova je stvaran, ali je donio i novo pitanje: koliko zaista znamo o dijelovima od kojih je naš proizvod sastavljen?

Literatura

  1. I. Sommerville: Software Engineering, 10th ed., Pearson, 2016 (poglavlje 16).
  2. C. Szyperski: Component Software, 2nd ed., Addison-Wesley, 2002.
  3. R. C. Martin: Clean Architecture, Prentice Hall, 2017 (dio o principima komponenata).

Zašto ovo poglavlje

U poglavlju 7 izabrali smo arhitekturu DeliveryApp 2.0: modularni monolit s jasnim granicama između narudžbi, dostave, plaćanja i obavještenja. Ovo poglavlje uzima te dijelove ozbiljno i pravi od njih komponente: dijelove s ugovorom, verzijom i vlastitim životom. Prvi dio objašnjava ideju programskog inženjerstva temeljenog na komponentama, odlike komponente, interfejse, koheziju i povezanost. Drugi dio daje principe i smjernice za dizajn komponenata, pokazuje kako se komponenta pravi kao paket sa semantičkom verzijom, i govori o rizicima ponovne upotrebe, od Ariane 5 do left-pada.

Riječi ovog poglavlja (1/2)

  • Komponenta – samostalna jedinica softvera s jasnim interfejsom, koja se isporučuje nezavisno i sklapa s drugim komponentama.
  • CBSE (component-based software engineering) – razvoj softvera sklapanjem gotovih i vlastitih komponenata.
  • Ponuđeni interfejs – operacije koje komponenta nudi drugima.
  • Zahtijevani interfejs – operacije koje komponenta traži od okoline da bi radila.
  • Ugovor – precizan opis interfejsa: ulazi, izlazi, greške, uslovi.
  • Kohezija – koliko dijelovi unutar komponente pripadaju zajedno.

Riječi ovog poglavlja (2/2)

  • Povezanost (coupling) – koliko komponenta zavisi od drugih.
  • Paket – komponenta spremna za instalaciju iz registra (pip/PyPI, NuGet, npm).
  • Semantičko verzioniranje – verzija oblika glavna.sporedna.zakrpa s tačno određenim značenjem.
  • Tranzitivna zavisnost – zavisnost moje zavisnosti.
  • SBOM (software bill of materials) – spisak svih komponenata od kojih je proizvod sastavljen.

Ciljevi poglavlja

Nakon poglavlja možete:

objasniti ideju CBSE i njene koristi; navesti odlike komponente po Szyperskom; razlikovati ponuđeni i zahtijevani interfejs i nacrtati UML dijagram komponenti; objasniti koheziju i povezanost; objasniti principe REP, CCP, CRP, ADP, SDP i SAP prostim riječima; primijeniti smjernice za dizajn komponente; napraviti Python paket sa semantičkom verzijom i reći kad se mijenja koji broj; objasniti rizike ponovne upotrebe i šta je SBOM.

Plan poglavlja – Predavanje 8: dva časa teorije i jedan čas dopunske prakse

ČasSadržajNa času
Teorija 18.1–8.4 CBSE, odlike, interfejsi, kohezija i povezanostLego kocka i utičnica; dijagram komponenti DeliveryApp
Teorija 28.5–8.8 Principi, smjernice, provođenje, riziciKoja je sljedeća verzija: 1.1.0 ili 2.0.0?
Dopunska praksaPaket deliveryapp-dostava sa semantičkom verzijompip install . i tri testa
Dio 1 · Predavanje 8

Dio 1 – Šta je komponenta

8.1 Ideja programskog inženjerstva temeljenog na komponentama

Lego kocke su najbolja slika komponente. Svaka kocka ima standardne čepiće (interfejs), pa se svaka može spojiti sa svakom, bez obzira na to ko ju je napravio i kada. Iz istih kocki prave se kuća, auto i svemirski brod. Niko ne pravi kocke iznova za svaku igračku.

Programsko inženjerstvo temeljeno na komponentama (CBSE) prenosi tu ideju u softver: proizvod se sklapa od komponenata, a ne piše od nule. Dio komponenata tim pravi sam (komponenta za obračun dostave), a dio uzima gotove (biblioteka za heširanje lozinki, okvir za web, klijent za sistem plaćanja).

Koristi:

  1. Brži razvoj – ne piše se ono što već postoji i radi.
  2. Pouzdanost – komponenta koju koriste hiljade projekata već je „istestirana” u praksi.
  3. Zamjenjivost – komponenta s istim interfejsom može se zamijeniti boljom.
  4. Podjela rada – svaki tim odgovara za svoje komponente.

8.1 Ideja programskog inženjerstva temeljenog na komponentama

Danas je CBSE svakodnevica: tipična web aplikacija sadrži više stotina paketa iz registara, a vlastitog koda je često manje od tuđeg.

Ukratko – 8.1 Ideja programskog inženjerstva temeljenog na komponentama

  • CBSE sklapa proizvod od vlastitih i gotovih komponenata, kao igračku od Lego kocki.
  • Koristi su brzina, pouzdanost, zamjenjivost i podjela rada.
  • Tipičan proizvod danas sadrži više tuđeg nego vlastitog koda.

8.2 Odlike komponente

Clemens Szyperski je u knjizi Component Software dao definiciju koja se najčešće navodi: komponenta je jedinica sastavljanja s ugovorom definisanim interfejsima i samo eksplicitnim zavisnostima od okoline; može se isporučiti nezavisno i sklapati s drugim komponentama, i to od strane trećih lica.

Prevedeno na pet odlika:

8.2 Odlike komponente

OdlikaŠta značideliveryapp-dostava
standardizovanaprati dogovoren model (npr. Python paket, .NET biblioteka)Python paket s pyproject.toml
nezavisnane traži skrivene stvari od okoline; sve zavisnosti su zapisanenema zavisnosti osim Pythona
sastavljivasav pristup ide kroz javni interfejsobracunaj(grad, km, iznos)
isporučivamože se instalirati i nadograditi posebnopip install deliveryapp-dostava==2.0.0
dokumentovanainterfejs je opisan tako da ga koristi neko ko ne vidi kodopis u modulu i README

Komponenta nije isto što i klasa. Klasa je jedinica koda; komponenta je jedinica isporuke. Komponenta obično sadrži više klasa, od kojih je većina skrivena, a vani se vidi samo interfejs.

Ukratko – 8.2 Odlike komponente

  • Po Szyperskom, komponenta je jedinica sastavljanja s ugovorom i eksplicitnim zavisnostima, koja se isporučuje nezavisno.
  • Odlike: standardizovana, nezavisna, sastavljiva, isporučiva, dokumentovana.
  • Klasa je jedinica koda, a komponenta jedinica isporuke.

8.3 Interfejsi i ugovor

Komponenta ima dvije vrste interfejsa. Analogija je električni aparat:

  • Ponuđeni interfejs je ono što aparat nudi: fen nudi topao zrak, dugme i dva stepena brzine.
  • Zahtijevani interfejs je ono što aparat traži: utičnicu od 230 V.

Fen radi u bilo kojoj kući koja ima tu utičnicu; kući je svejedno koji fen je uključen. Tako i komponenta deliveryapp-narudzbe zahtijeva interfejse obracunaj(), naplati(), posalji() i udaljenost(), a ne zna i ne zanima je ko ih pruža.

flowchart LR
    N["«komponenta»<br/>deliveryapp-narudzbe"]
    D["«komponenta»<br/>deliveryapp-dostava 2.0.0"]
    iD(("obracunaj()"))
    D --- iD
    N -.->|"zahtijeva"| iD
Slika 8.1 – Komponente DeliveryApp 2.0: ponuđeni i zahtijevani interfejsi
Slika 8.1 – Komponente DeliveryApp 2.0: ponuđeni i zahtijevani interfejsi

8.3 Interfejsi i ugovor

Ugovor je precizan opis interfejsa. Za obracunaj(grad, km, iznos) ugovor kaže:

  • ulazi: oznaka grada (A, B, C), udaljenost u kilometrima, iznos artikala u centima;
  • izlaz: objekat Obracun s gradom, iznosom dostave u centima i kratkim opisom;
  • greške: nepoznat grad → KeyError; udaljenost izvan zone ili iznos ispod 5,00 € → ValueError;
  • garancije: od 30,00 € dostava je 0; rezultat ne zavisi od vremena ni od stanja baze.

Ugovor se ne mijenja „usput”. Ako se mora promijeniti, mijenja se glavna verzija (8.6).

Ukratko – 8.3 Interfejsi i ugovor

  • Ponuđeni interfejs je ono što komponenta nudi, zahtijevani ono što traži, kao aparat i utičnica.
  • UML dijagram komponenti crta komponente, interfejse (kružići) i zavisnosti (isprekidane strelice).
  • Ugovor opisuje ulaze, izlaze, greške i garancije.

8.4 Kohezija i povezanost

Dva pojma odlučuju da li je podjela na komponente dobra:

  • Kohezija – koliko dijelovi unutar komponente pripadaju zajedno. Visoka kohezija: komponenta radi jednu stvar (obračun dostave). Niska kohezija: komponenta razno u kojoj su obračun dostave, slanje SMS-a i izvoz u Excel.
  • Povezanost – koliko komponenta zavisi od drugih. Niska povezanost: dostava ne zna ništa o plaćanju. Visoka povezanost: promjena u plaćanju ruši dostavu.

Cilj je uvijek isti: visoka kohezija, niska povezanost. Analogija: dobro organizovana kuhinja ima ladicu za pribor i ladicu za začine (visoka kohezija), a da biste uzeli kašiku ne morate izvaditi začine (niska povezanost).

Slika 8.2 – Visoka kohezija i niska povezanost naspram suprotnog
Slika 8.2 – Visoka kohezija i niska povezanost naspram suprotnog

8.4 Kohezija i povezanost

Na času

Tim predlaže komponentu deliveryapp-alati u kojoj bi bili formatiranje cijene (24,50 €), provjera e-mail adrese, računanje udaljenosti i slanje push obavještenja. Šta nije u redu i kako biste je razdvojili?

Ukratko – 8.4 Kohezija i povezanost

  • Kohezija je koliko dijelovi unutar komponente pripadaju zajedno; povezanost koliko komponenta zavisi od drugih.
  • Cilj: visoka kohezija, niska povezanost.
  • Komponenta „razno” ili „alati” je znak niske kohezije.

Provjeri se

  1. Koja je razlika između klase i komponente? Klasa je jedinica koda, a komponenta jedinica isporuke koja obično sadrži više klasa.
  2. Šta je zahtijevani interfejs? Operacije koje komponenta traži od okoline da bi radila.
  3. Kakvu koheziju i povezanost želimo? Visoku koheziju i nisku povezanost.

Odgovori: tipka R ili klik na zamućeno polje.

Dio 2 · Predavanje 8

Dio 2 – Dizajn i provođenje

8.5 Principi dizajna temeljenog na komponentama

Robert C. Martin je opisao šest principa za komponente. Tri govore šta ide zajedno u komponentu, a tri kako komponente zavise jedna od druge.

Šta ide zajedno (kohezija):

PrincipProstim riječimaU DeliveryApp
REP – ponovna upotreba = izdanjeono što se ponovo koristi mora imati verziju i izdanjedeliveryapp-dostava ima verziju 2.0.0 i bilješke o izdanju
CCP – zajedničko zatvaranjeu istu komponentu ide ono što se mijenja iz istog razloga i u isto vrijemetarife i obračun dostave mijenjaju se zajedno, pa su zajedno
CRP – zajednička ponovna upotrebane tjeraj korisnika da zavisi od onoga što ne koristidostava ne nosi kod za SMS, pa ko koristi dostavu ne mora instalirati SMS

Kako zavise (povezanost):

8.5 Principi dizajna temeljenog na komponentama

PrincipProstim riječimaU DeliveryApp
ADP – bez ciklusazavisnosti ne smiju praviti krugnarudžbe → dostava, ali dostava ne zavisi od narudžbi
SDP – zavisi od stabilnogzavisi od onoga što se rjeđe mijenja od tebeekran zavisi od narudžbi, narudžbe od tarife
SAP – stabilno je apstraktnokomponente od kojih mnogi zavise neka budu apstraktne (interfejsi)ServisMapa je interfejs, a konkretna firma je zamjenjiva

Zašto je ciklus opasan? Ako narudžbe zavise od dostave, a dostava od narudžbi, nijedna se ne može izgraditi, testirati ni isporučiti bez druge: dvije komponente su zapravo jedna, samo s dva imena. Ciklus se prekida tako što se zajednički dio izdvoji ili se uvede interfejs (inverzija zavisnosti).

Slika 8.3 – Zavisnosti bez ciklusa, prema stabilnim komponentama
Slika 8.3 – Zavisnosti bez ciklusa, prema stabilnim komponentama

Ukratko – 8.5 Principi dizajna temeljenog na komponentama

  • REP, CCP i CRP odlučuju šta ide u komponentu: ono što se izdaje, mijenja i koristi zajedno.
  • ADP, SDP i SAP odlučuju o zavisnostima: bez ciklusa, prema stabilnom, a stabilno neka bude apstraktno.
  • Ciklus pretvara dvije komponente u jednu i prekida se izdvajanjem ili interfejsom.

8.6 Smjernice za dizajn komponenata

Praktične smjernice koje tim DeliveryApp koristi:

  1. Mali, jasan interfejs. Što manje javnih funkcija, to manje obećanja koja se moraju čuvati. deliveryapp-dostava izvozi tri imena: Obracun, obracunaj, gradovi. Sve ostalo (npr. _Tarifa, _TARIFE) počinje donjom crtom i nije dio ugovora.
  2. Nepromjenjivi objekti na granici. Komponenta vraća objekat koji se ne može mijenjati (frozen=True), da pozivalac ne pokvari stanje komponente.
  3. Jasne greške. Svaka greška ugovora ima svoj tip i poruku.
  4. Bez skrivenih zavisnosti. Ništa iz globalnih varijabli, okruženja ili baze, osim ako to piše u ugovoru.
  5. Dokumentacija i primjer. README s primjerom poziva od tri reda.
  6. Testovi uz komponentu. Komponenta se isporučuje sa svojim testovima.
  7. Semantička verzija. Verzija glavna.sporedna.zakrpa ima tačno značenje:

8.6 Smjernice za dizajn komponenata

PromjenaKoji broj rastePrimjer za deliveryapp-dostava
ispravka greške, ugovor istizakrpa1.1.0 → 1.1.1: ispravljeno zaokruživanje na 8,0 km
nova mogućnost, stari pozivi i dalje radesporedna1.0.0 → 1.1.0: dodane tarife po gradu, stari poziv dostava(km, iznos) radi za Grad A
promjena koja kvari stare poziveglavna1.1.0 → 2.0.0: obracunaj() vraća Obracun umjesto broja; stari poziv uklonjen

Kad DeliveryApp kaže da zavisi od deliveryapp-dostava>=2.0,<3, zna da će dobiti sve ispravke i nove mogućnosti verzije 2, a da ga ništa neće pokvariti bez upozorenja. Pravila semantičkog verzioniranja zapisana su na stranici semver.org.

Česta zabluda

„Verzija je samo broj za marketing.” U svijetu komponenata verzija je obećanje. Ako komponenta u zakrpi promijeni ugovor, hiljade projekata koji su vjerovali obećanju mogu se pokvariti preko noći.

Ukratko – 8.6 Smjernice za dizajn komponenata

  • Smjernice: mali interfejs, nepromjenjivi objekti na granici, jasne greške, bez skrivenih zavisnosti, dokumentacija, testovi.
  • Semantička verzija: zakrpa za ispravku, sporedna za kompatibilnu novost, glavna za promjenu koja kvari stare pozive.
  • Verzija je obećanje korisnicima komponente.

8.7 Provođenje dizajna komponenata

Kako tim DeliveryApp od dijela koda pravi komponentu, korak po korak:

  1. Prepoznati kandidata. Dio s visokom kohezijom koji se mijenja iz jednog razloga i koji bi mogao trebati i drugima: obračun dostave (trebaće ga i budući proizvod za dostavu iz apoteka).
  2. Definisati ugovor. Ponuđeni interfejs (obracunaj), zahtijevani (nijedan), greške, garancije.
  3. Izdvojiti kod. Premjestiti kod iza interfejsa, sakriti sve ostalo.
  4. Napisati testove komponente. Prije nego što je drugi počnu koristiti.
  5. Spakovati. Python: pyproject.toml s imenom i verzijom; C#: projekat biblioteke (.csproj) i NuGet paket.
  6. Objaviti. U javni registar (PyPI, NuGet, npm) ili u interni registar firme.
  7. Održavati. Bilješke o izdanju, semantičke verzije, ispravke sigurnosnih problema.

Paket deliveryapp-dostava (primjeri/paket/deliveryapp-dostava) ima ovu strukturu:

8.7 Provođenje dizajna komponenata

deliveryapp-dostava/
├── pyproject.toml
├── src/deliveryapp_dostava/__init__.py
└── tests/test_komponenta.py

pyproject.toml opisuje paket:

[project]
name = "deliveryapp-dostava"
version = "2.0.0"
description = "Obračun dostave po tarifi grada (komponenta proizvoda DeliveryApp 2.0)"
requires-python = ">=3.10"

A ponuđeni interfejs izgleda ovako:

8.7 Provođenje dizajna komponenata

@dataclass(frozen=True)
class Obracun:
    grad: str
    dostava: int      # centi
    opis: str


def obracunaj(grad: str, km: float, iznos: int) -> Obracun:
    t = _TARIFE.get(grad)
    if t is None:
        raise KeyError(f"nepoznat grad: {grad}")
    if km < 0 or km > t.max_km:
        raise ValueError("adresa je izvan zone dostave")
    if iznos < MIN_NARUDZBA:
        raise ValueError("iznos je manji od najmanje narudžbe")
    if iznos >= BESPLATNA_OD:
        return Obracun(grad, 0, "besplatna dostava od 30,00 €")
    dodatni = math.ceil(max(0, km - t.ukljuceno_km))
    return Obracun(grad, t.osnovna + t.po_km * dodatni, f"osnovna + {dodatni} km")

Nakon pip install . u čistom virtuelnom okruženju, poziv obracunaj("B", 4.2, 2150) vraća Obracun(grad='B', dostava=380, opis='osnovna + 3 km'), a tri testa komponente prolaze.

U C# isti posao radi projekat biblioteke: dotnet new classlib -n DeliveryApp.Dostava, verzija u .csproj (<Version>2.0.0</Version>), pakovanje sa dotnet pack i objava u NuGet registar. Javne su samo klase i metode označene sa public; ostalo je internal i ne vidi se izvan komponente.

Ukratko – 8.7 Provođenje dizajna komponenata

  • Provođenje: prepoznati kandidata, definisati ugovor, izdvojiti kod, testovi, spakovati, objaviti, održavati.
  • Python komponenta je paket s pyproject.toml; C# komponenta je biblioteka i NuGet paket.
  • Sve osim ponuđenog interfejsa je sakriveno (donja crta u Pythonu, internal u C#).

8.8 Ponovna upotreba i njeni rizici

Ponovna upotreba štedi vrijeme, ali komponenta koja je radila u jednom okruženju ne mora raditi u drugom, a svaka tuđa komponenta je i tuđi rizik.

8.8 Ponovna upotreba i njeni rizici

Iz stvarnog svijeta

Raketa Ariane 5 eksplodirala je na prvom letu, 4. juna 1996, oko četrdeset sekundi nakon polijetanja. Softver za inercijalni navigacioni sistem preuzet je s rakete Ariane 4, gdje je godinama radio bez greške. Ariane 5 je, međutim, brža, pa je jedna vrijednost horizontalne brzine postala prevelika za pretvaranje iz 64-bitnog decimalnog broja u 16-bitni cijeli broj. Pretvaranje nije bilo zaštićeno, sistem je prijavio grešku, i raketa je skrenula s putanje i raspala se. Istražna komisija je utvrdila da funkcija koja je izazvala grešku Ariani 5 nakon polijetanja nije ni bila potrebna. Komponenta je bila ispravna za svoj stari ugovor, a niko nije provjerio da li taj ugovor važi u novom okruženju.

8.8 Ponovna upotreba i njeni rizici

Rizici ponovne upotrebe i odgovori:

8.8 Ponovna upotreba i njeni rizici

RizikPrimjerOdgovor
komponenta ne odgovara novom okruženjuAriane 5provjeriti ugovor i granice u novom okruženju; testovi s novim vrijednostima
komponenta nestaneleft-pad, 2016interni registar ili keš paketa; zaključane verzije
ranjivost u komponentiranjivost u biblioteci Log4j otkrivena u decembru 2021, koja je pogodila ogroman broj Java sistemapraćenje ranjivosti (npr. Dependabot), brza nadogradnja
zlonamjerna komponentapaket s imenom sličnim popularnom, s ubačenim kodomprovjera izvora i imena, potpisani paketi
tranzitivne zavisnostimoja zavisnost zavisi od stotinu drugihspisak svih zavisnosti, redovna provjera
licencabiblioteka s licencom koja traži objavu vlastitog kodaprovjera licenci prije uključivanja

Zaključavanje verzija. Fajl s tačnim verzijama svih zavisnosti, uključujući tranzitivne (npr. requirements.txt s ==, poetry.lock, packages.lock.json u .NET-u), garantuje da se proizvod sutra gradi od istih dijelova kao danas.

SBOM (software bill of materials) je deklaracija sastava proizvoda, kao spisak sastojaka na pakovanju hrane: sve komponente, njihove verzije i licence. Kad se objavi nova ranjivost, firma sa SBOM-om za minut zna da li je pogođena. Zakoni o sajber sigurnosti (npr. evropski Akt o sajber otpornosti) sve češće traže takav spisak za proizvode koji se prodaju.

Ukratko – 8.8 Ponovna upotreba i njeni rizici

  • Komponenta ispravna u jednom okruženju može biti pogrešna u drugom, kao kod Ariane 5.
  • Rizici: drugo okruženje, nestanak, ranjivost, zlonamjerni paket, tranzitivne zavisnosti, licence.
  • Odgovori: provjera ugovora, zaključane verzije, interni registar, praćenje ranjivosti, provjera licenci.
  • SBOM je deklaracija sastava proizvoda.

Provjeri se

  1. Šta kaže princip ADP? Zavisnosti između komponenata ne smiju praviti ciklus.
  2. Komponenta dobija novu funkciju, a stari pozivi rade. Koja verzija slijedi nakon 1.1.0? 1.2.0.
  3. Šta je SBOM? Spisak svih komponenata, verzija i licenci od kojih je proizvod sastavljen.

Odgovori: tipka R ili klik na zamućeno polje.

Dopunska praksa · Predavanje 8

Dopunska praksa – paket `deliveryapp-dostava`

Dopunska praksa – paket deliveryapp-dostava

Cilj je napraviti komponentu kao Python paket, instalirati je i promijeniti verziju po pravilima. Trajanje: jedan čas.

Korak 1 – Paket

Kopirajte folder primjeri/paket/deliveryapp-dostava u svoj repozitorij. Napravite virtuelno okruženje i instalirajte paket:

python -m venv .venv
.venv\Scripts\activate          (Linux/macOS: source .venv/bin/activate)
pip install -e .
python -c "import deliveryapp_dostava as z; print(z.__version__, z.obracunaj('B', 4.2, 2150))"
pip install pytest
pytest tests

Korak 2 – Zakrpa

Pronađite ili zamislite ispravku koja ne mijenja ugovor (npr. bolja poruka greške). Napravite je, promijenite verziju u pyproject.toml i __init__.py na 2.0.1 i dopišite stavku u CHANGELOG.md.

Korak 3 – Sporedna verzija

Dodajte Grad D (2,00 € do 4 km, 0,40 € po km, najdalje 15 km) i test za njega. Stari pozivi rade, pa je nova verzija 2.1.0. Provjerite: koliko je dostava za N-1001 (21,50 €, 4,2 km) u Gradu D?

Korak 4 – Glavna verzija (samo zapis)

U CHANGELOG.md opišite promjenu koja bi tražila 3.0.0 (npr. iznos se vraća kao Decimal u eurima umjesto int u centima) i šta korisnici komponente moraju promijeniti.

Korak 5 – SBOM (opcionalno)

Pokrenite pip list --format=freeze u virtuelnom okruženju i sačuvajte izlaz kao docs/sastav.txt. To je najjednostavniji spisak sastava; profesionalni alati prave SBOM u standardnim formatima (CycloneDX, SPDX).

Rezultat: paket koji se instalira, testovi koji prolaze, verzija 2.1.0 i CHANGELOG.md s tri stavke.

Vježbe

Vježbe za studenta

Rješenja su sakrivena – tipka R ili klik na okvir.

Vježba za studenta 1 – verzije.

Zadatak

Komponenta deliveryapp-placanje je u verziji 3.4.2. Koja je sljedeća verzija za: a) ispravku greške u zaokruživanju; b) novi način plaćanja (stari rade); c) uklanjanje starog načina plaćanja „pouzećem”; d) ispravku pravopisne greške u poruci?

Vježba za studenta 1 – verzije. – rješenje

Rješenje (R)

a) 3.4.3; b) 3.5.0; c) 4.0.0 (stari pozivi prestaju raditi); d) 3.4.3 ako se poruka ne smatra dijelom ugovora (ako je pozivaoci porede kao tekst, sigurnije je smatrati je promjenom ugovora).

Vježba za studenta 2 – kohezija i povezanost.

Zadatak

Komponenta deliveryapp-narudzbe direktno čita tabelu tarifa iz baze da bi izračunala dostavu, umjesto da pozove deliveryapp-dostava. Šta je loše i šta predlažete?

Vježba za studenta 2 – kohezija i povezanost. – rješenje

Rješenje (R)

Povezanost je visoka i skrivena: narudžbe zavise od unutrašnje strukture podataka dostave, pa svaka promjena tabele kvari narudžbe, a pravilo obračuna postoji na dva mjesta (krši DRY i CCP). Prijedlog: narudžbe pozivaju samo ponuđeni interfejs obracunaj(); tabela tarifa je privatna stvar komponente dostave.

Vježba za studenta 3 – ciklus.

Zadatak

deliveryapp-narudzbe zavisi od deliveryapp-obavjestenja (šalje poruku o promjeni stanja), a deliveryapp-obavjestenja zavisi od deliveryapp-narudzbe (čita detalje narudžbe za tekst poruke). Kako prekinuti ciklus?

Vježba za studenta 3 – ciklus. – rješenje

Rješenje (R)

Npr. narudžbe objavljuju događaj „stanje promijenjeno” sa svim podacima potrebnim za poruku (broj, novo stanje, telefon), preko reda poruka ili interfejsa koji pripada narudžbama. Obavještenja reaguju na događaj i više ne zovu narudžbe. Zavisnost ide samo u jednom smjeru (ADP).

Vježba za studenta 4 – ponovna upotreba.

Zadatak

Tim želi u DeliveryApp uključiti besplatnu biblioteku za crtanje mape koju je napisao jedan programer i koja nije ažurirana tri godine. Napišite pet pitanja koja tim treba postaviti prije odluke.

Vježba za studenta 4 – ponovna upotreba. – rješenje

Rješenje (R)

1) Kakva je licenca i da li dozvoljava upotrebu u komercijalnom proizvodu? 2) Ima li poznatih ranjivosti i ko ih ispravlja? 3) Od čega ona zavisi (tranzitivne zavisnosti)? 4) Šta radimo ako nestane ili prestane raditi – možemo li je držati u internom registru ili zamijeniti? 5) Da li njen ugovor odgovara našim uslovima (broj tačaka na mapi, mobilni uređaji, brzina)?

Sažetak u pet rečenica

  1. McIlroy je 1968. sanjao katalog softverskih komponenata, a left-pad 2016. pokazao je da taj katalog postoji, ali i da od jedanaest redova tuđeg koda mogu zavisiti hiljade projekata.
  2. Komponenta je jedinica sastavljanja i isporuke s ugovorom, ponuđenim i zahtijevanim interfejsom i eksplicitnim zavisnostima, a dobra podjela ima visoku koheziju i nisku povezanost.
  3. Principi REP, CCP i CRP odlučuju šta ide zajedno u komponentu, a ADP, SDP i SAP traže zavisnosti bez ciklusa, prema stabilnim i apstraktnim komponentama.
  4. Komponenta se pravi kao paket (pip, NuGet) s malim interfejsom, testovima i semantičkom verzijom, gdje zakrpa znači ispravku, sporedna verzija kompatibilnu novost, a glavna promjenu koja kvari stare pozive.
  5. Ponovna upotreba nosi rizike, od drugog okruženja (Ariane 5) do nestanka, ranjivosti i licenci, pa se verzije zaključavaju, zavisnosti prate, a sastav proizvoda vodi u SBOM-u.

Pitanja za ponavljanje

  1. Šta je McIlroy predložio 1968. i šta se desilo s left-padom 2016?
  2. Šta je CBSE i koje su njegove koristi?
  3. Navedite Szyperskijevu definiciju komponente i pet odlika komponente.
  4. Koja je razlika između komponente i klase?
  5. Šta su ponuđeni i zahtijevani interfejs? Objasnite analogijom s aparatom i utičnicom.
  6. Šta sadrži ugovor komponente? Napišite ugovor za obracunaj.
  7. Šta su kohezija i povezanost i kakve ih želimo?
  8. Objasnite principe REP, CCP i CRP.
  9. Objasnite principe ADP, SDP i SAP. Zašto je ciklus zavisnosti opasan?
  10. Navedite smjernice za dizajn komponente. Šta znače tri broja semantičke verzije?
  11. Opišite korake provođenja dizajna komponente i kako se komponenta pakuje u Pythonu i C#.
  12. Šta se desilo s Ariane 5 i koji su rizici ponovne upotrebe? Šta je SBOM?