Projektovanje informacionih sistema · Poglavlje 6 · Sedmica 6

Strukturni model – klase i objekti

Dio 1 – Objekat i klasa

Dio 2 – Veze i višestrukost

Dio 3 – Domenski model DeliveryApp

Praksa – classDiagram; kostur klasa u Pythonu

Materijale priredio Erkan Islamović

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

Šta učimo ovog semestra

Petnaest sedmica, svaka s tri časa teorije i tri časa prakse. Danas: poglavlje 6 (Sedmica 6, označeno). Isti primjer kroz knjigu: DeliveryApp, narudžba N-1001 (24,50 €).

Sed.PoglavljeSed.Poglavlje
1P1 Zašto projektujemo9P9 Arhitektura
2P2 Životni ciklus10P10 Integracija i API
3P3 Zahtjevi11P11 Korisnički interfejs
4P4 Poslovni procesi12P12 Sigurnost i privatnost
5P5 UML i slučajevi korištenja13P13 Realno vrijeme i IoT
6P6 Klase i objekti14P14 Kvalitet i isporuka
7P7 Sekvence i stanja15P15 AI i završni projekat
8P8 Baza podataka
Mermaid crta · Python izvršava · SQLite čuva · Git pamti verzije

Literatura

  1. B. Popović, K. Kuk: Informacioni sistemi, Kriminalističko-policijski univerzitet, Beograd, 2017.
  2. J. S. Valacich, J. F. George: Modern Systems Analysis and Design, 9th ed., Pearson, 2020.
  3. L. Jelenković: Sustavi za rad u stvarnom vremenu – skripta, FER, Zagreb, 2015.
  4. D. Milićev: Programiranje u realnom vremenu – skripta, Beograd, 2002.
  5. V. Kovačević, M. Popović: Sistemska programska podrška u realnom vremenu 1, FTN, Novi Sad, 2013.

Priča za početak

Priča za početak

Početkom šezdesetih godina dvojica norveških naučnika, Ole-Johan Dahl i Kristen Nygaard, radili su u Norveškom računskom centru u Oslu na simulacijama: kako se ponaša red brodova u luci, kako teče posao u fabrici, gdje se stvaraju gužve. Programi tog vremena bili su dugi spiskovi naredbi, i u njima se teško vidjelo šta je brod, a šta dizalica. Dahl i Nygaard su smislili drugačiji način: program se sastoji od objekata koji liče na stvari iz stvarnog svijeta, a svaki objekat ima svoje podatke i svoje ponašanje. Opis po kojem se prave svi brodovi iste vrste nazvali su klasa. Jezik koji su napravili zvao se Simula, a njegova verzija iz 1967. godine prvi je jezik s klasama, objektima i nasljeđivanjem. Kasnije su iz te ideje nastali Smalltalk, C++, Java, Python i C#, pa danas skoro svaki programer misli u objektima. Dahl i Nygaard su 2001. godine dobili Turingovu nagradu, koja se često naziva „Nobelovom nagradom za računarstvo”, upravo za objektno orijentisano programiranje.

Zašto ovo poglavlje

U poglavlju 5 opisali smo šta DeliveryApp radi za svakog aktera. Sada pitamo: šta DeliveryApp zna? Koje „stvari” postoje u sistemu, šta o svakoj pamti i kako su povezane? Odgovor daje strukturni model, a u UML-u ga crtamo dijagramom klasa. Prvo objašnjavamo objekat i klasu, uz Python kod. Zatim učimo veze među klasama: asocijaciju, višestrukost, kompoziciju i nasljeđivanje. Na kraju iz teksta vizije pronalazimo klase i crtamo domenski model DeliveryApp. Na praktičnoj nastavi isti model crtamo u Mermaidu i pišemo ga kao Python klase koje računaju 24,50 €.

Riječi ovog poglavlja (1/3)

  • Objekat – jedna konkretna stvar u sistemu, s vlastitim podacima (npr. narudžba N-1001).
  • Klasa – opis po kojem se prave svi objekti iste vrste (npr. klasa Narudžba).
  • Atribut – podatak koji objekat pamti (broj, stanje, udaljenost).
  • Operacija (metoda) – nešto što objekat zna uraditi (dodati stavku, izračunati ukupno).
  • Instanca – drugo ime za objekat napravljen po klasi.
  • Enkapsulacija – skrivanje unutrašnjih podataka objekta, tako da se mijenjaju samo kroz njegove operacije.

Riječi ovog poglavlja (2/3)

  • Asocijacija – veza između klasa koja kaže da se njihovi objekti „poznaju” (kupac pravi narudžbu).
  • Višestrukost – koliko objekata jedne klase može biti povezano s jednim objektom druge (1, 0..1, 0.., 1..).
  • Kompozicija – jaka veza „dio–cjelina”: dio ne postoji bez cjeline (stavka bez narudžbe).
  • Agregacija – slaba veza „dio–cjelina”: dio postoji i sam (dostavljač bez tima).
  • Nasljeđivanje (generalizacija) – posebna klasa preuzima sve od opšte i dodaje svoje (Kupac je vrsta Korisnika).
  • Domenski model – dijagram klasa koji opisuje pojmove posla, bez tehničkih detalja.

Riječi ovog poglavlja (3/3)

  • Dijagram objekata – slika stvarnih objekata i njihovih vrijednosti u jednom trenutku.

Ciljevi poglavlja

Nakon poglavlja možete:

objasniti razliku između objekta i klase na primjeru narudžbe; za objekat navesti stanje, ponašanje i identitet; nacrtati klasu u UML-u s atributima, tipovima, operacijama i vidljivošću; objasniti enkapsulaciju i zašto stanje narudžbe ne mijenjamo direktno; nacrtati asocijaciju s višestrukošću i pročitati je kao rečenicu; razlikovati kompoziciju, agregaciju i običnu asocijaciju; prepoznati kada je nasljeđivanje dobar izbor, a kada nije; iz teksta vizije izdvojiti kandidate za klase, atribute i operacije; nacrtati domenski model DeliveryApp u Mermaidu; napisati kostur klasa u Pythonu i provjeriti da daje 24,50 € za N-1001; nacrtati dijagram objekata za N-1001.

Plan poglavlja – Sedmica 6: tri časa teorije i tri časa praktične nastave

ČasSadržajNa času
Teorija 16.1–6.3 Objekat, klasa, enkapsulacijaKalup i kolači; klasa Narudžba u UML-u i Pythonu
Teorija 26.4–6.6 Asocijacija, višestrukost, kompozicija, nasljeđivanje„Jedan kupac pravi nula ili više narudžbi”
Teorija 36.7–6.9 Od imenica do klasa; domenski model; objektiDomenski model DeliveryApp; N-1001 kao objekti
Praksa 1–3Mermaid classDiagram; Python klasemodel.py računa 24,50 €
Dio 1 · Sedmica 6

Dio 1 – Objekat i klasa

6.1 Objekat

Objekat je jedna konkretna stvar u sistemu. Narudžba N-1001 je objekat. Picerija R-1 je objekat. Pizza Margarita na jelovniku R-1 je objekat. Svaki objekat ima tri osobine:

  1. Stanje – podaci koje objekat u ovom trenutku pamti. Narudžba N-1001 pamti: broj „N-1001”, kupca K-01, restoran R-1, udaljenost 4,2 km, dvije stavke i stanje NOVA.
  2. Ponašanje – šta objekat zna uraditi. Narudžba zna dodati stavku, izračunati ukupnu cijenu i promijeniti stanje.
  3. Identitet – po čemu je ovaj objekat on, a ne neki drugi. Dvije narudžbe mogu imati iste stavke i istu adresu, ali su ipak dvije različite narudžbe (N-1001 i N-1007), kao što dvije sestre bliznakinje nisu ista osoba.

Objekat može predstavljati i nešto što se ne može dodirnuti: narudžbu, plaćanje, kod popusta. Pravilo je jednostavno: ako sistem o nečemu mora pamtiti podatke i to nešto treba razlikovati od drugih iste vrste, to je kandidat za objekat.

Ukratko – 6.1 Objekat

  • Objekat je jedna konkretna stvar u sistemu, opipljiva ili ne (narudžba, restoran, plaćanje).
  • Objekat ima stanje (podatke), ponašanje (šta zna uraditi) i identitet (po čemu je baš on).
  • Ako sistem o nečemu pamti podatke i razlikuje ga od drugih, to je kandidat za objekat.

6.2 Klasa

Klasa je opis po kojem se prave svi objekti iste vrste. Klasa Narudžba kaže: svaka narudžba ima broj, kupca, restoran, udaljenost, stavke i stanje, i svaka zna izračunati ukupnu cijenu. Svaki pojedinačni objekat (N-1001, N-1002…) je instanca te klase: ima istu građu, ali svoje vrijednosti.

Najbolja slika iz života je kalup za kolače. Kalup je klasa: određuje oblik. Kolači su objekti: svaki ima isti oblik, ali jedan je s čokoladom, drugi s vanilom, a treći je pojeden. Kalup se ne jede; kolač se jede. Isto tako, klasa Narudžba ne košta ništa; narudžba N-1001 košta 24,50 €.

6.2 Klasa

Klasa u UML-u

U dijagramu klasa klasa se crta kao pravougaonik s tri dijela:

  1. gore ime klase (imenica u jednini, veliko početno slovo: Narudzba);
  2. u sredini atributi, u obliku ime: tip;
  3. dolje operacije, u obliku ime(parametri): tip rezultata.

Ispred atributa i operacija stoji znak vidljivosti: + znači javno (svi smiju koristiti), - znači privatno (samo sam objekat), # znači zaštićeno (objekat i njegove podklase). Evo klase Narudzba kao Mermaid teksta:

classDiagram
    class Narudzba {
        +broj: str
        +udaljenost_km: float
        -stanje: str
        +dodaj(jelo: Jelo, kolicina: int)
        +artikli() int
        +dostava() int
        +ukupno() int
        +promijeni(novo: str)
    }

6.2 Klasa

Primijetite da u imenima pišemo „Narudzba” bez slova ž. Mermaid i većina programskih jezika dozvoljavaju i naša slova, ali mnogi alati i baze s njima imaju problema, pa je dobra navika da se u imenima u kodu koriste samo engleska slova, a u tekstu za ljude puni dijakritici.

6.2 Klasa

Ista klasa u Pythonu

Dijagram i kod opisuju isto. Ovako izgleda dio klase u Pythonu (cijeli fajl je primjeri/deliveryapp/model.py):

@dataclass
class Narudzba:
    broj: str
    kupac: Kupac
    restoran: Restoran
    udaljenost_km: float
    kod: str | None = None
    stavke: list = field(default_factory=list)
    stanje: str = "NOVA"

    def dodaj(self, jelo, kolicina=1):
        self.stavke.append(Stavka(jelo, kolicina))

    def artikli(self):
        return sum(s.iznos() for s in self.stavke)

    def ukupno(self):
        a = self.artikli()
        return a - popust(a, self.kod) + self.dostava()

Oznaka @dataclass kaže Pythonu da sam napravi dio koda koji puni atribute; mi pišemo samo atribute i operacije. Iznosi su u centima (950 znači 9,50 €), da bi se izbjegle greške zaokruživanja decimalnih brojeva u računaru; na ekranu ih pretvaramo nazad u eure.

Slika 6.1 – Klasa je kalup, objekti su kolači: klasa Narudzba i tri njene instance
Slika 6.1 – Klasa je kalup, objekti su kolači: klasa Narudzba i tri njene instance

Ukratko – 6.2 Klasa

  • Klasa je opis po kojem se prave objekti iste vrste, kao kalup za kolače.
  • Svaki objekat je instanca klase: ista građa, svoje vrijednosti.
  • U UML-u klasa je pravougaonik s imenom, atributima i operacijama; + je javno, − privatno.
  • Isti model se piše i kao Python klasa; iznosi su u centima da se izbjegne zaokruživanje.

6.3 Enkapsulacija

Zamislite da svako ko ima pristup narudžbi može direktno napisati n.stanje = "OTKAZANA", u bilo kom trenutku. Šta sprečava da neko otkaže narudžbu koja je već na putu, suprotno pravilu PP-6? Ništa.

Enkapsulacija (od latinskog „u kapsulu”) znači da objekat skriva svoje unutrašnje podatke, a mijenja ih samo kroz svoje operacije, koje provjeravaju pravila. Narudžba ne dozvoljava da joj neko spolja postavi stanje; dozvoljava samo poziv promijeni("OTKAZANA"), a ta operacija prvo provjeri je li prelaz dozvoljen:

def promijeni(self, novo):
    if novo not in PRELAZI[self.stanje]:
        raise ValueError(f"nedozvoljen prelaz {self.stanje} -> {novo}")
    self.stanje = novo

Zato je u UML-u atribut stanje označen s - (privatno), a operacija promijeni s + (javno).

6.3 Enkapsulacija

Slika iz života: bankomat. Novac je u kapsuli; ne možete otvoriti bankomat i uzeti koliko hoćete. Možete samo pozvati operaciju „podigni 50 €”, a bankomat provjeri PIN i stanje računa prije nego što isplati. Pravila su na jednom mjestu, unutar objekta, i niko ih ne može zaobići.

Česta zabluda

„Enkapsulacija je skrivanje od drugih programera, iz nepovjerenja.” Nije. Enkapsulacija čuva pravila na jednom mjestu. Kad se pravilo PP-6 promijeni, mijenja se samo operacija promijeni, a ne stotinu mjesta u kodu koja su direktno pisala stanje.

Ukratko – 6.3 Enkapsulacija

  • Enkapsulacija znači da objekat skriva svoje podatke i mijenja ih samo kroz operacije koje provjeravaju pravila.
  • Stanje narudžbe je privatno; mijenja se samo operacijom promijeni(), koja provjerava PP-6.
  • Kao bankomat: novac je u kapsuli, a isplata ide samo kroz operaciju s provjerom.

Provjeri se

  1. Koje tri osobine ima svaki objekat? Stanje, ponašanje i identitet.
  2. Šta je razlika između klase i objekta? Klasa je opis (kalup), a objekat je konkretna instanca s vrijednostima (kolač).
  3. Zašto je atribut stanje privatan? Da bi se mijenjao samo kroz operaciju koja provjerava dozvoljene prelaze.

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

Dio 2 · Sedmica 6

Dio 2 – Veze između klasa

6.4 Asocijacija i višestrukost

Klase same nisu mnogo korisne. Narudžba mora znati čija je i iz kojeg restorana. Veza koja kaže da se objekti dvije klase „poznaju” zove se asocijacija i crta se linijom između klasa. Na krajevima linije piše višestrukost: koliko objekata s te strane može biti povezano s jednim objektom s druge strane.

6.4 Asocijacija i višestrukost

OznakaZnačenjePrimjer
1tačno jedannarudžba ima tačno jednog kupca
0..1nijedan ili jedannarudžba ima nijednog ili jednog dostavljača (dok ga ne dobije)
0.. ili nijedan ili višekupac može imati nula ili više narudžbi
1..*jedan ili višenarudžba ima bar jednu stavku

Asocijacija se čita kao rečenica, u oba smjera. Za vezu Kupac "1" --> "0..*" Narudzba : pravi:

  • „Jedan kupac pravi nula ili više narudžbi.”
  • „Jedna narudžba pripada tačno jednom kupcu.”

Ako se rečenica ne slaže sa stvarnošću, dijagram je pogrešan. Može li narudžba imati dva kupca? U DeliveryApp ne. Može li kupac postojati bez ijedne narudžbe? Da, tek se registrovao. Zato je višestrukost na strani narudžbe 0.., a ne 1...

6.4 Asocijacija i višestrukost

Višestrukost nije sitnica. Ona direktno postaje pravilo u bazi (poglavlje 8) i provjera u kodu. Ako je na strani stavki 1..*, sistem ne smije sačuvati narudžbu bez ijedne stavke.

Na času

Pročitajte naglas, u oba smjera: Narudzba "0..*" --> "0..1" Dostavljac : nosi. Zašto je na strani dostavljača 0..1, a ne 1? (Jer narudžba u stanju NOVA još nema dostavljača.)

Ukratko – 6.4 Asocijacija i višestrukost

  • Asocijacija je linija koja kaže da se objekti dvije klase poznaju.
  • Višestrukost na krajevima linije kaže koliko objekata može biti povezano: 1, 0..1, 0.. ili 1...
  • Asocijacija se čita kao rečenica u oba smjera, i mora se slagati sa stvarnošću.
  • Višestrukost postaje pravilo u bazi i provjera u kodu.

6.5 Kompozicija i agregacija

Neke asocijacije su posebne: jedna strana je cjelina, a druga njen dio. UML razlikuje dvije jačine te veze.

Kompozicija je jaka veza: dio ne postoji bez cjeline i nestaje zajedno s njom. Crta se punim rombom (◆) na strani cjeline. Stavka „2 × Pizza Margarita” nema smisla bez narudžbe N-1001: ako se narudžba obriše, briše se i stavka. Isto važi za jelo na jelovniku restorana u DeliveryApp: kad restoran napusti DeliveryApp, njegov jelovnik nestaje s njim.

Agregacija je slaba veza: dio postoji i sam, a cjelina ga samo okuplja. Crta se praznim rombom (◇). Dostavljač D-2 može biti u timu „Jutarnja smjena”, ali ako se tim raspusti, D-2 i dalje postoji i vozi.

Slika iz života: kuća i sobe su kompozicija; kad se kuća sruši, sobe nestaju s njom. Fudbalski tim i igrači su agregacija; kad se tim raspusti, igrači prelaze u druge timove.

U praksi se agregacija rijetko crta, jer se teško razlikuje od obične asocijacije. Kompozicija je korisnija, jer kaže nešto važno za bazu i kod: brisanje cjeline briše i dijelove.

Ukratko – 6.5 Kompozicija i agregacija

  • Kompozicija (pun romb) je jaka veza: dio ne postoji bez cjeline, kao stavka bez narudžbe.
  • Agregacija (prazan romb) je slaba veza: dio postoji i sam, kao dostavljač bez tima.
  • Kompozicija kaže da brisanje cjeline briše i njene dijelove.

6.6 Nasljeđivanje

Kupac, dostavljač i osoblje restorana imaju mnogo zajedničkog: svi se prijavljuju, svi imaju ime, e-mail i lozinku. Umjesto da ista tri atributa pišemo tri puta, napravimo opštu klasu Korisnik, a posebne klase je nasljeđuju: preuzimaju sve od nje i dodaju svoje. Kupac dodaje adrese, Dostavljac dodaje vrstu vozila.

U UML-u se nasljeđivanje (generalizacija) crta punom linijom sa šupljim trouglom na strani opšte klase. Čita se „je vrsta”: kupac je vrsta korisnika.

classDiagram
    Korisnik <|-- Kupac
    Korisnik <|-- Dostavljac
    Korisnik <|-- OsobljeRestorana
    class Korisnik {
        +email: str
        -lozinka_hes: str
        +prijavi(email, lozinka) bool
    }
    class Kupac {
        +adrese: list
    }
    class Dostavljac {
        +vozilo: str
    }

6.6 Nasljeđivanje

Kada nasljeđivanje nije dobar izbor

Nasljeđivanje je moćno, ali se lako zloupotrebi. Dva testa:

  1. Test „je vrsta”. Ako rečenica „B je vrsta A” zvuči čudno, nasljeđivanje je pogrešno. „Stavka je vrsta narudžbe”? Ne; stavka je dio narudžbe, pa je to kompozicija.
  2. Test zamjene. Svuda gdje sistem očekuje opštu klasu mora moći raditi i posebna, bez iznenađenja. Ako bi PlacanjeGotovinom moralo baciti grešku na operaciju „vrati novac na karticu”, onda možda ne treba nasljeđivati PlacanjeKarticom, nego obje klase trebaju nasljeđivati opštije Placanje.

U savremenom projektovanju često se kaže: radije sastavljaj nego nasljeđuj (composition over inheritance). Ako kupac i dostavljač samo dijele adresu, bolje je da oba imaju objekat Adresa nego da nasljeđuju klasu koja „ima adresu”.

Slika 6.2 – Četiri vrste veza: asocijacija, kompozicija, agregacija i nasljeđivanje
Slika 6.2 – Četiri vrste veza: asocijacija, kompozicija, agregacija i nasljeđivanje

Ukratko – 6.6 Nasljeđivanje

  • Nasljeđivanje znači da posebna klasa preuzima sve od opšte i dodaje svoje; crta se šupljim trouglom.
  • Nasljeđivanje se čita „je vrsta”: kupac je vrsta korisnika.
  • Ako „je vrsta” zvuči čudno, ili posebna klasa ne može zamijeniti opštu, nasljeđivanje je pogrešno.
  • Često je bolje sastavljati objekte (kupac ima adresu) nego nasljeđivati.

Provjeri se

  1. Pročitajte vezu Narudzba "1" -- "1.." Stavka. Jedna narudžba se sastoji od jedne ili više stavki, a stavka ne postoji bez svoje narudžbe.
  2. Koja je razlika između kompozicije i agregacije? Kod kompozicije dio ne postoji bez cjeline, a kod agregacije postoji i sam.
  3. Da li je Stavka vrsta Narudžbe? Ne; stavka je dio narudžbe, pa je veza kompozicija, a ne nasljeđivanje.

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

Dio 3 · Sedmica 6

Dio 3 – Domenski model DeliveryApp

6.7 Od imenica do klasa

Odakle znamo koje klase DeliveryApp treba? Najjednostavnija tehnika je analiza teksta: uzmemo viziju, korisničke priče i specifikacije slučajeva korištenja i podvučemo imenice i glagole.

  • Imenice su kandidati za klase ili atribute.
  • Glagoli su kandidati za operacije ili asocijacije.

Iz specifikacije UC-01 (poglavlje 5): „Kupac bira jela i količine; sistem pokazuje zbir artikala. Kupac unosi adresu dostave. Sistem traži udaljenost od servisa mapa… Sistem pravi narudžbu u stanju NOVA i prikazuje je restoranu.”

Kandidate zatim sortiramo:

6.7 Od imenica do klasa

ImenicaOdlukaZašto
Kupacklasasistem pamti njegove podatke i razlikuje kupce
Jeloklasaima naziv i cijenu; restoran ih ima više
Količinaatribut (stavke)broj, nema svoje ponašanje
Zbir artikalaoperacijaračuna se iz stavki, ne pamti se
Adresaklasa ili atributklasa, ako kupac ima više adresa; inače atribut
Udaljenostatribut (narudžbe)broj u km
Servis mapanije klasa domenavanjski sistem (akter), ne pojam posla
Sistemodbacitito je DeliveryApp sam
Narudžbaklasasrce sistema
Stanjeatributjedna od sedam vrijednosti
Restoranklasaima jelovnik i narudžbe

6.7 Od imenica do klasa

Primijetite tri pravila: ono što se računa nije atribut (zbir artikala računamo, ne pamtimo, jer bi inače mogao biti netačan); vanjski sistemi nisu klase domena; i „sistem” se odbacuje.

Ukratko – 6.7 Od imenica do klasa

  • Analiza teksta: imenice su kandidati za klase ili atribute, glagoli za operacije ili veze.
  • Kandidati se sortiraju: šta se pamti i razlikuje je klasa; jednostavan broj je atribut; ono što se računa je operacija.
  • Vanjski sistemi i riječ „sistem” nisu klase domena.

6.8 Domenski model

Domenski model je dijagram klasa koji opisuje pojmove posla i njihove veze, bez tehničkih detalja (nema baze, ekrana, servera). Razumije ga i vlasnik restorana: on će reći „narudžba uvijek ima bar jedno jelo”, a mi ćemo to pročitati kao višestrukost 1..*.

Domenski model DeliveryApp:

classDiagram
    class Kupac {
        +oznaka: str
        +telefon: str
    }
    class Adresa {
        +ulica: str
        +broj: str
    }
    class Restoran {
        +oznaka: str
        +naziv: str
        +otvoren: bool
    }
    class Jelo {
        +naziv: str
        +cijena: int
        +dostupno: bool
    }
    class Narudzba {
        +broj: str
        +udaljenost_km: float
        -stanje: str
        +artikli() int
        +dostava() int
        +ukupno() int
        +promijeni(novo)
    }
    class Stavka {
        +kolicina: int
        +iznos() int
    }
    class Dostavljac {
        +oznaka: str
        +vozilo: str
    }
    class Placanje {
        +iznos: int
        +odobreno: bool
    }
    class KodPopusta {
        +kod: str
        +procenat: int
        +max_iznos: int
    }
    Kupac "1" --> "1..*" Adresa : ima
    Kupac "1" --> "0..*" Narudzba : pravi
    Restoran "1" *-- "1..*" Jelo : nudi
    Narudzba "0..*" --> "1" Restoran : iz
    Narudzba "1" *-- "1..*" Stavka : sadrži
    Stavka "0..*" --> "1" Jelo : od
    Narudzba "0..*" --> "0..1" Dostavljac : nosi
    Narudzba "1" --> "0..1" Placanje : plaćena
    Narudzba "0..*" --> "0..1" KodPopusta : koristi

6.8 Domenski model

Pročitajmo nekoliko veza kao rečenice: „Jedan restoran nudi jedno ili više jela, a jelo ne postoji bez restorana.” „Jedna narudžba sadrži jednu ili više stavki.” „Svaka stavka je od tačno jednog jela, a jedno jelo može biti u mnogo stavki.” „Narudžba može koristiti nijedan ili jedan kod popusta.”

Jedno pitanje vrijedi postaviti glasno: zašto Stavka ima samo količinu, a ne i cijenu? Ako restoran sutra poskupi Margaritu na 10,00 €, da li se mijenja i cijena već plaćene narudžbe N-1001? Ne smije! Zato u stvarnom sistemu stavka pamti cijenu u trenutku narudžbe (cijena_u_trenutku: int). Ovo je primjer kako domenski model otkriva poslovno pravilo koje niko nije izgovorio. Dopisujemo ga u backlog i u model.

Slika 6.3 – Domenski model DeliveryApp
Slika 6.3 – Domenski model DeliveryApp

Ukratko – 6.8 Domenski model

  • Domenski model je dijagram klasa s pojmovima posla, bez tehničkih detalja.
  • DeliveryApp ima devet klasa: Kupac, Adresa, Restoran, Jelo, Narudžba, Stavka, Dostavljač, Plaćanje i KodPopusta.
  • Svaka veza se čita kao rečenica koju potvrđuje čovjek iz posla.
  • Model je otkrio novo pravilo: stavka pamti cijenu u trenutku narudžbe.

6.9 Dijagram objekata

Dijagram klasa je kalup. Ponekad je korisno nacrtati i kolače: stvarne objekte s vrijednostima u jednom trenutku. To je dijagram objekata. Ime objekta piše se podvučeno, u obliku ime: Klasa, a umjesto tipova stoje vrijednosti.

Narudžba N-1001, u trenutku kad je plaćena:

6.9 Dijagram objekata

ObjekatVrijednosti
k01: Kupacoznaka = "K-01"
r1: Restoranoznaka = "R-1", naziv = "Picerija"
margarita: Jelonaziv = "Pizza Margarita", cijena = 950
sok: Jelonaziv = "Sok", cijena = 250
n1001: Narudzbabroj = "N-1001", udaljenost_km = 4.2, stanje = "NOVA"
s1: Stavkakolicina = 2 → margarita
s2: Stavkakolicina = 1 → sok

6.9 Dijagram objekata

Iz ovih vrijednosti operacije daju: s1.iznos() = 2 × 950 = 1900; s2.iznos() = 250; n1001.artikli() = 2150; n1001.dostava() = 300; n1001.ukupno() = 2450 centi = 24,50 €.

Dijagram objekata je odličan za provjeru modela: ako ne možete nacrtati stvaran primjer s vrijednostima, model ima rupu. Probajte, na primjer, nacrtati narudžbu bez stavki: višestrukost 1..* kaže da to nije dozvoljeno, i dijagram objekata to odmah pokaže.

Slika 6.4 – Dijagram objekata: narudžba N-1001 u trenutku plaćanja
Slika 6.4 – Dijagram objekata: narudžba N-1001 u trenutku plaćanja

Ukratko – 6.9 Dijagram objekata

  • Dijagram objekata prikazuje stvarne objekte i njihove vrijednosti u jednom trenutku.
  • Za N-1001 operacije daju 2150 centi artikala, 300 centi dostave i ukupno 2450 centi, odnosno 24,50 €.
  • Ako se ne može nacrtati stvaran primjer s vrijednostima, model ima rupu.

Provjeri se

  1. Zašto „zbir artikala” nije atribut? Jer se računa iz stavki; da se pamti, mogao bi postati netačan.
  2. Zašto Servis mapa nije klasa domenskog modela? To je vanjski sistem (akter), a ne pojam posla.
  3. Koliko je n1001.ukupno()? 2450 centi, odnosno 24,50 €.

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

Praksa · Sedmica 6

Praktična nastava – domenski model u Mermaidu i Pythonu

Praktična nastava – domenski model u Mermaidu i Pythonu

Cilj je nacrtati domenski model DeliveryApp i napisati ga kao Python klase koje računaju cijenu narudžbe po pravilima PP-1 do PP-5. Fajlovi idu u modeli/ i kod/ repozitorija deliveryapp-projekat.

Korak 1 – Analiza teksta

U modeli/klase.md napravite tabelu imenica iz svoje specifikacije UC-01 i UC-02 (poglavlje 5) s odlukom: klasa, atribut, operacija ili odbaciti, i razlogom. Najmanje 15 imenica.

Korak 2 – Domenski model u Mermaidu

  1. U modeli/klase.md prepišite domenski model iz 6.8 (blok mermaid).
  2. Dodajte atribut cijena_u_trenutku: int u klasu Stavka.
  3. Dodajte klasu Ocjena (kupac ocjenjuje restoran od 1 do 5 nakon isporuke) s vezama i višestrukošću. Napišite obje rečenice za svaku novu vezu.
  4. Dodajte nasljeđivanje Korisnik → Kupac, Dostavljac, OsobljeRestorana iz 6.6.
  5. Provjerite da se dijagram iscrtava (pregled u VS Codeu ili [mermaid.live](https://mermaid.live)).

Korak 3 – Python klase

  1. U folder kod/ kopirajte deliveryapp.py i model.py iz primjeri/deliveryapp/ (repozitorij udžbenika) ili ih prepišite.
  2. Pokrenite u terminalu:
python model.py

Očekivani ispis:

N-1001 artikli 21,50 € dostava 3,00 € ukupno 24,50 €
sa kodom 22,35 €

Korak 3 – Python klase

  1. Dodajte u klasu Narudzba operaciju promijeni(novo) iz 6.3, koja koristi rječnik PRELAZI iz deliveryapp.py.
  2. Na kraj model.py dodajte provjere:
n.promijeni("PRIHVAĆENA")
n.promijeni("U_PRIPREMI")
try:
    n.promijeni("OTKAZANA")
    print("GREŠKA: otkazivanje u pripremi je prošlo")
except ValueError:
    print("ispravno: otkazivanje u pripremi nije dozvoljeno (PP-6)")
  1. Napravite i narudžbu N-1002 (4 × Ćevapi, 2,5 km) i provjerite da je ukupno 3200 centi.

Korak 4 – Dijagram objekata

Nacrtajte (u Mermaidu kao classDiagram s imenima objekata, ili na papiru pa slikajte) dijagram objekata za N-1002 u trenutku isporuke: kupac, restoran, jelo, stavka, narudžba, dostavljač D-3 i plaćanje.

Korak 5 – AI kao recenzent modela (opcionalno)

Dajte AI asistentu svoj Mermaid domenski model i zatražite: „Pročitaj svaku vezu kao rečenicu u oba smjera i reci mi koja ti zvuči sumnjivo za aplikaciju za dostavu hrane.” Za svaku primjedbu odlučite sami da li je opravdana. Zatražite i da iz modela napiše Python klase; pokrenite ih i uporedite rezultat s 24,50 €.

Rezultat koji se predaje: modeli/klase.md (analiza teksta i domenski model s dodacima), kod/model.py koji ispisuje 24,50 €, 22,35 €, poruku o PP-6 i 32,00 € za N-1002, te dijagram objekata za N-1002.

Vježbe

Vježbe za studenta

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

Vježba za studenta 1 – objekat ili klasa.

Zadatak

Šta je klasa, a šta objekat? a) Pizza Margarita na jelovniku R-1; b) Jelo; c) dostavljač D-3; d) Plaćanje; e) plaćanje karticom za N-1001 u iznosu 24,50 €.

Vježba za studenta 1 – objekat ili klasa. – rješenje

Rješenje (R)

Klase: b) Jelo, d) Plaćanje. Objekti: a) (instanca klase Jelo), c) (instanca klase Dostavljač), e) (instanca klase Plaćanje).

Vježba za studenta 2 – višestrukost.

Zadatak

Napišite višestrukost i pročitajte vezu u oba smjera: a) Restoran – Narudžba; b) Kupac – Adresa (kupac mora imati bar jednu adresu da bi naručio, a može ih sačuvati više); c) Narudžba – Plaćanje.

Vježba za studenta 2 – višestrukost. – rješenje

Rješenje (R)

a) Restoran "1" <-- "0.." Narudzba: jedan restoran ima nula ili više narudžbi; jedna narudžba je iz tačno jednog restorana. b) Kupac "1" --> "1.." Adresa: jedan kupac ima jednu ili više adresa; jedna adresa pripada jednom kupcu. c) Narudzba "1" --> "0..1" Placanje: jedna narudžba ima nijedno ili jedno plaćanje (prije naplate nijedno); plaćanje pripada tačno jednoj narudžbi.

Vježba za studenta 3 – kompozicija, agregacija ili nasljeđivanje.

Zadatak

a) Restoran i Jelo; b) Tim dostavljača i Dostavljač; c) PlacanjeKarticom i Placanje; d) Narudžba i Kupac.

Vježba za studenta 3 – kompozicija, agregacija ili nasljeđivanje. – rješenje

Rješenje (R)

a) kompozicija (jelo u DeliveryApp ne postoji bez restorana); b) agregacija (dostavljač postoji i bez tima); c) nasljeđivanje (plaćanje karticom je vrsta plaćanja); d) obična asocijacija (kupac nije dio narudžbe, niti obrnuto).

Vježba za studenta 4 – računanje kroz objekte.

Zadatak

Napravite (na papiru) objekte za narudžbu N-1005: kupac K-05 iz Salatarnice R-3 naručuje 2 × Salata s piletinom (9,00 €) i 2 × Limunada (3,00 €), na 6,5 km, s kodom STUDENT10. Šta vraćaju artikli(), dostava() i ukupno() (u centima)?

Vježba za studenta 4 – računanje kroz objekte. – rješenje

Rješenje (R)

artikli = 2 × 900 + 2 × 300 = 2400 centi (24,00 €). Dostava: 24,00 € < 30,00 €, a preko 3 km je 3,5 km, dakle četiri započeta kilometra: 200 + 4 × 50 = 400 centi (4,00 €). Popust: 10 % od 2400 = 240 centi (manje od 500). ukupno = 2400 − 240 + 400 = 2560 centi = 25,60 €.

Vježba za studenta 5 – nedostajuće pravilo.

Zadatak

Kupac K-01 je naručio N-1001 kad je Margarita koštala 9,50 €. Sedmicu kasnije restoran je poskupi na 10,00 € i kupac otvori istoriju narudžbi. Šta pokazuje model iz 6.8 bez dodatka iz koraka 2, a šta s dodatkom? Kako se to zove u projektovanju?

Vježba za studenta 5 – nedostajuće pravilo. – rješenje

Rješenje (R)

Bez dodatka stavka pokazuje na jelo, pa bi se ukupno ponovo izračunalo s novom cijenom: 2 × 10,00 + 2,50 + 3,00 = 25,50 €, što nije iznos koji je kupac platio (24,50 €). S atributom cijena_u_trenutku stavka pamti 950 centi, pa istorija pokazuje tačnih 24,50 €. Ovo je primjer da se istorijski podaci zamrzavaju u trenutku transakcije; to je poslovno pravilo koje je otkrio model, a ne korisnik.

Sažetak u pet rečenica

  1. Objekat je konkretna stvar u sistemu sa stanjem, ponašanjem i identitetom, a klasa je opis po kojem se prave objekti iste vrste, ideja koja potiče iz jezika Simula iz 1967.
  2. U UML-u klasa je pravougaonik s imenom, atributima i operacijama, a enkapsulacija skriva podatke tako da se mijenjaju samo kroz operacije koje provjeravaju pravila.
  3. Asocijacija s višestrukošću (1, 0..1, 0.., 1..) čita se kao rečenica u oba smjera, kompozicija znači da dio ne postoji bez cjeline, a nasljeđivanje da je posebna klasa vrsta opšte.
  4. Klase se nalaze analizom teksta, a domenski model DeliveryApp ima devet klasa i otkrio je novo pravilo da stavka pamti cijenu u trenutku narudžbe.
  5. Isti model napisan kao Python klase računa za N-1001 2150 centi artikala, 300 centi dostave i ukupno 24,50 €, a dijagram objekata provjerava model na stvarnom primjeru.

Pitanja za ponavljanje

  1. Ko su bili Dahl i Nygaard i šta je donio jezik Simula?
  2. Koje tri osobine ima objekat? Objasnite ih na narudžbi N-1001.
  3. Objasnite razliku između klase i objekta pomoću kalupa za kolače.
  4. Kako se klasa crta u UML-u? Šta znače znakovi + i −?
  5. Šta je enkapsulacija i zašto je stanje narudžbe privatno?
  6. Šta je asocijacija i šta je višestrukost? Navedite četiri oznake višestrukosti.
  7. Pročitajte u oba smjera vezu između kupca i narudžbe.
  8. Koja je razlika između kompozicije i agregacije? Dajte primjer za svaku.
  9. Šta je nasljeđivanje i koja dva testa pokazuju da je pogrešno upotrijebljeno?
  10. Šta znači „radije sastavljaj nego nasljeđuj”?
  11. Kako se analizom teksta dolazi do klasa? Navedite tri pravila sortiranja kandidata.
  12. Šta je domenski model i ko ga treba razumjeti?
  13. Zašto stavka treba pamtiti cijenu u trenutku narudžbe?
  14. Šta je dijagram objekata i čemu služi?