Kihagyás

Modellezés

Előadásfóliák

Vizuális modellezés

A szoftverfejlesztés ugye nem úgy kezdődik, hogy elkezdem ütni a billentyűzetet és írni a kódot. Hanem előbb szépen végiggondolom, hogy mit (követelmény-specifikáció) és hogyan (tervezés) szeretnék csinálni. Modellezni ebben a két fázisban szokás.

A modell a problémát, annak az elemeit, azok működését, viselkedését (és ezáltal a probléma megoldási módszerét) fogja leírni (ez a modell reprezentációs tulajdonsága) olyan szinten, ami már számunkra megfelelő. A jó modell ritkán (sohasem) teljes, mindig csak a szükséges elemeket tartalmazza (ez a modellek redukciós tulajdonsága), de a probléma korrekt (nem feltétlenül tökéletes) megoldására teljességgel alkalmas (ez pedig a gyakorlatias tulajdonság).

Ferdehajítás modellje

Mindenki ismeri az α szöggel v kezdősebességgel kilőtt test pozíciójának számítási módját a t időpontban:

  • a vízszintes sx koordináta értéke sx = cos(α) × v × t
  • a függőleges sy koordináta értéke sy = sin(α) × v × t - (g × t² / 2),

ahol g a nehézségi gyorsulás.

Ezzel egész jól lehet számolni pontszerű testet feltételezve, síkon, egyenletes gravitációs mezőben, légellenállás hiányában. Valójában ezen feltételek egyike sem áll meg, de amíg a tárgy nem elég nagy ahhoz, hogy a perdülete bekavarjon, nem repül túl messzire ahhoz, hogy a föld görbülete számítson, nem megy elég magasra ahhoz, hogy számottevően megváltozzon a rá ható nehézségi gyorsulás, és a repülés ideje alatt a légellenállásból eredő lassulása elhanyagolhatóan kicsi, addig ez a modell is megteszi.

És még ezt is lehet fokozni a relativisztikus sebességekkel, tömeggel és idővel, ami mondjuk egy GPS műhold pályájának számításakor már igenis számít!

És miért vizuális? Mert az embert ezt tudja a leggyorsabban feldolgozni, így vagyunk összerakva. Ahelyett, hogy szövegben körülírnánk, amit vagy elmondani, vagy elolvasni kell, megmutatjuk az ábrát, és mindenki érti, miről van szó. Már ha mindenki ismeri azokat a szabványos grafikus jelöléseket, amit használunk. Persze a vizualitás mellett a természetes nyelvet is lehet, és néha kell is használni (az egyes elemeket például érdemesebb megfelelően elnevezni, mint mondjuk pusztán külön színekkel jelölni). Ha jól csináljuk a modellezést, azzal hosszú távon rengeteg időt és pénzt spórolhatunk.

A siker háromszöge

Ahhoz, hogy a modellezés és ezáltal az egész fejlesztés sikeres legyen, három dolog kell:

  • egy folyamat,
  • egy jelölésrendszer,
  • és egy eszköz.

Fejlesztési folyamatból nagyon sokféle van, de alapvetően két nagyobb típust szokás megkülönböztetni.

  • A lineáris modellek --mint például a Vízesés modell vagy a V-modell-- szerint a fejlesztés lépéseit sorban egymásután hajtjuk végre, minden fázist teljesen végig kell vinni mielőtt a következőt elkezdenénk, és visszalépések legfeljebb korrekciós okokból lehetségesek. Vagyis az elején össze kell gyűjtenünk az összes követelményt és el kell készítenünk a teljes modellt, csak utána állhatunk neki az implementációnak.
  • Az iteratív modellek --Scrum, eXtreme Programming-- ezzel szemben, vagy inkább erre épülve megengedik, sőt előírják a folyamat "újrakezdését". Vagyis ott teljesen természetes, ha az elején nincs meg az összes követelmény, ha a modell csak a probléma egy részét írja le, hiszen ott a lehetőség, hogy később visszatérjünk ezekhez, és bővítsük/módosítsuk őket, akár az eddig elkészült implementáció (prototípus) tesztelése során szerzett tapasztalatokat is felhasználva.

SDLC
A két alapvető fejlesztési folyamattípus

Jelölésrendszerből is sok van, és most a természetes nyelvi leírást is ide sorolhatjuk. A legelterjedtebb jelölésrendszer --legalábbis objektumorientált fejlesztés során-- a UML (Unified Modelling Language). Ez egy egységes jelölőrendszer, mellyel a modell különféle előre definiált vetületeit (pl. működés, felépítés, viselkedés) jelölhetjük --mindegyiket a saját, mégis egységes jelölésmódjával--, de akár új nézeteket is definiálhatunk.

Az eszköz pedig lehet olyan egyszerű, mit a ceruza és a papír (nagyon gyakran ma is így kezdik, vagy filccel és táblával), valamilyen rajzolóprogram, vagy egészen profi modellezőeszköz is.

Modell, nézet, diagram

Ezt a három foglamat érdemes megkülönböztetni.

A modell az, ami --a probléma helyes megoldásához minimálisan szükséges módon-- leírja a valós vagy elképzelt rendszerünket. Ez a modell "bármit" tartalmazhat, ami a korrekt megoldáshoz szükséges, többet pedig nem nagyon kellene neki. A modell kellőképpen összetett is lehet, és általában a rendszerünk adatait, szerkezetét, a működését, és a viselkedését is leírja.

A nézeteket akkor használjuk, amikor a modellünk egy-egy részlete érdekel bennünket. Ha például csak arra vagyunk kíváncsiak, hogy milyen adatokat kell majd tárolni, akkor nem érdekes, hogy a modellünk szerint ezeket hogyan dolgozzuk fel, vagy hogy a rendszer hogyan viselkedik a feldolgozás közben (projektív nézet). Ha pedig csak a teljes rendszer egy kisebb részét vizsgáljuk, akkor a többi részét tudjuk figyelmen kívül hagyni (szelektív nézet). Vagyis egy-egy nézetben a modell egyes elemeit figyelmen kívül hagyjuk.

A diagram pedig nem más, mint egy nézet (grafikus) ábrázolása.

Ferdehajítás modellje

A ferdehajítás előbb ismertetett modelljénél például az adat nézet elemei a következők lehetnek:

  • bemeneti adatok:
    • g nehézségi gyosrulás, m/s²-ben kifejezve,
    • α eldobási szög, a vízszintes 0-hoz képest, szögben kifejezve,
    • v kezdősebesség, m/s-ban kifejezve,
    • t időpillanat (az "eldobáshoz képest eltelt idő") s-ban mérve;
  • kimeneti adatok:
    • s kétdimenziós elmozdulásvektor, (sx, sy) alakban, ahol x a vízszintes és y a függőleges tengely.

Mint látható, ebben a nézetben nem érdekes, hogy hogyan számoljuk ki s értékét, még az sem igazán, hogy ez majd a t időpillanathoz fog tartozni (bár ezek az indormációk is részei a modellnek). A számolás módját a működési nézet mutatja meg.

A fenti egy projektív nézet volt, egy szelektív nézetre példa az, ha csak a repülés közbeni (földetérés előtti) vízszintes elmozdulással törödünk. Ebben az esetben az α szög, v kezdősebesség, t időpont, sx vízszintes irányú elmozdulás adatok szerepelnek, a számítási mód pedig:

  • sx = cos(α) × v × t

lesz. Mint látszik, a g nehézségi gyorsulás és az sy függőleges elmozdulás adatok, valamint ez utóbbi számítási módja most nem érdekesek.

A UML nagyon sokféle nézetet (és hozzájuk tartozó diagramokat) definiál. Az egyik jellemző csoportosítás (a fent említett adat-működés-viselkedés felosztás mellett) az architektúra 4+1 nézete:

SDLC
Az architektúra 4+1 nézete

  • Használati eset nézet: Ebben a nézetben a rendszer működését modellezzük bizonyos szereplők (actor-ok, személyek, "külső" szoftverek, vagy a rendszer egységei) szemszögéből. Maga a használati eset egy folyamatleírás, lépésekkel, esetleges alternatív ágakkal, visszalépésekkel, elternatív befejezésekkel.

  • Logikai nézet: A logikai nézet a végfelhasználó szemszögéből mutatja be a rendszer funkcionalitását, nagyjából azt, hogy mit tud a rendszer, hogyan/mire használható, mit csinál, hogyan működik.

  • Komponens nézet: A komponens nézetet leginkább a programozók használják. A rendszer megvalósításának egységeit, elemeit, azok jellemzőit, tulajdonságait, használati módjait tudjuk ábrázolni vele.

  • Folyamat nézet: A folyamat nézetben a rendszer futás közbeni működésére koncentrálunk, milyen folyamatok hogyan zajlanak, az egyes egységek, modulok hogyan kommunikálnak, maga a rendszer hogyan viselkedik.

  • Telepítési nézet: A telepítési nézet megmutatja, hogy a szoftver egyes komponensei fizikailag hová lettek telepítve illetve milyen (fizikai) csatornákon kapcsolódnak egymáshoz.

UML diagramokból három nagyobb fajtát tudunk megkülönböztetni:

  • Használati eset diagramok: A rendszer különféle használati esetei közötti kapcsolatokat írják le. Például amikor egy folyamat része egy nagyobb folyamatnak (PIN kód megadása ATM-es készpénzfelvételkor), vagy valamilyen feltételek esetében kiegészíti azt (SMS küldés, ha a kétfaktoros azonosítás be van kapcsolva). Fontos, hogy egy konkrét használati eset az egy (általában szöveges, pontokba szedett) folyamatleírás, ennek részleteit a használati eset diagram nem tartalmazza.

  • Statikus diagramok: A rendszer és a rendszer által kezelt adatok szerkezetét, típusait írják le. A rendszer/megvalósítás elemeire, azok felépítésére és kapcsolataira koncentrálnak.

  • Dinamikus diagramok: A rendszer működését, viselkedését írják le. Azt, hogy a rendszer, annak egyes elemei hogyan dolgozzák fel a bemenő adatokat és állítják elő a kimenetet, a rendszer és egyes elemei hogyan kommunikálnak egymással és a külvilággal, és hogyan viselkednek amikor különféle módon "megszólítjuk" őket.

SDLC
A UML diagramok főbb típusai

OOP alapfogalmak

Az OOP alapfogalmainak bevezetésénél a modellezésből indulunk ki: van egy létező vagy elképzelt rendszerünk, és ezt a rendszert szeretnénk modellezni.

Objektum

A rendszerünkben különféle entitások azonosíthatók, amelyek a rendszerben kommunikálnak egymással, reagálnak egymásra; tulajdonképpen ezeknek a reakcióknak a dinamikája adja ki a rendszerünk működését. Ezeknek a "valós" entitásoknak a modelljei az objektumok. Minden objektum rendelkezik állapottal, viselkedéssel és identitással.

Az objektum állapota egy adott pillanatra jellemző. Az objektumnak a létezése során rengeteg állapota lehet, egy adott időpillanatban viszont csak egy. Az objektum állapotait az attribútumai, pontosabban ezek aktuális értékei határozzák meg, ezek az objektum tulajdonságai.

Az objektum viselkedése két dolgot takar. Egyrészt azt, hogy milyen külső ingerekre, eseményekre tud reagálni, másrészt, hogy ezt hogyan teszi (ahol a hogyan egyfajta viselkedésminta, vagy algoritmus, aminek a pontos "lefutása" rengeteg egyéb paramétertől, köztük az objektum aktuális állapotától is függhet). Az objektum viselkedését az objektum operációi határozzák meg. Ha egy operáció létezik, az jelzi, hogy mire tud reagálni az objektum, az operáció "tartalma" pedig a reakció mikéntjét, a hogyant írja le. Egy operációnak lehetnek paraméterei, amik befolyásolhatják a működését. Azonos peremfeltételek (azonos argumentum-értékek, objektum-állapot, stb.) esetén a konkrét válaszreakció is mindig ugyanaz lesz, eltérő peremfeltételek esetén a konkrét reakció is eltérhet.

Az identitás azt jelenti, hogy két objektum akkor is megkülönböztethető, ha az attribútumaik és operációik alapján teljesen egyformák. Ekkor is meg tudom mondani, hogy az két külön objektum, az egyik az egyik, a másik pedig a másik.

Objektum példa

Ha a modellezendő rendszerünkben szerepel például Buksi, a kis barna kutyánk, őt modellezhetjük egy "kutyus" objektummal. Mivel a modellt megpróbáljuk a minimálisra redukálni, az objektumunknak (önkényes döntéssel) mindössze három attribútuma lesz:

  • A neve, ami egy sztring, a kutyusunké éppen "Buksi".
  • A színe, ami egy szín, a kutyusunké éppen barna.
  • Egy jellemző, hogy éhes-e, ami igen vagy nem lehet, most legyen igen.

Bár a név és a szín állandónak látszik (tapasztalatból mondom, hogy egyik sem az), az látszik, hogy legalább az éhes-e azért időnként változik. Ehhez a három attribútumhoz rendelt érték együtt határozza meg a "kutyus" objektumunk állapotát, bármelyik megváltozik, akkor az objektumunk állapota is változik.

Az objektumunk viselkedését operációkkal adhatjuk meg. Most (szintén önkényesen) három operációt adunk meg:

  • Az alszik() operációt, aminek hatására a kutyus objektumunk elalszik (majd valamikor felébred). Tegyük fel, hogy a kutyánk alvás után, ébredéskor éhes lesz. Ez azt jelenti, hogy ez az operáció megváltoztathatja az objektum állapotát: az éhes-e attribútumot igenre állítja.
  • Az eszik() operációt, ami után a kutyának elmúlik az éhsége, vagyis az éhes-e attribútumának értéke nem lesz.
  • Definiálhatunk még egy ugat() operációt, ami viszont nem fogja megváltoztatni a kutyus objektumunk állapotát. Ennek ellenére nem feltétlenül felesleges, hiszen ha a teljes rendszerben gondolkodunk, az ugatással megijeszthet mondjuk egy macskát anélkül, hogy a saját állapota változna. (Szintén tapasztalat alapján: ha modelleztük volna a kutya lelki állapotát, azaz lenne még egy boldog attribútumunk is, a macska megijesztése azt biztosan befolyásolná.)

Ami látszik: a kutyus objektum három eseményre tud reagálni, az alszik(), eszik() és ugat() eseményekre, és azt is megadtuk, hogy ezekre hogyan reagál.

Ha ezek után egy másik kutyát is modellezni szeretnénk, aki szintén barna, és (agykapacitásunk kímélése érdekében) szintén a Buksi nevet kapta, akkor már nyilván két objektumunk lesz. Ez a két objektum akkor is két külön objektum marad, ha történetesen egyszerre etetjük meg őket az eszik() operáció segítségével, és ennek következtében egyik sem lesz éhes (mivel a kutyákra nem érvényes a Pauli-elv, a két objektum lehet ugyanazon állapotban). Attól még, hogy ugyanaz lesz az állapotuk, nem olvadnak össze egyetlen objektummá. (Ha megtennék, akkor a világon összesen legfeljebb két barna Buksi lehetne, és mindig pontosan az egyik lenne éhes; vagyis, ha az egyik enne, a másik megéhezne, vagy valamelyik kutya eltűnne.) Vagyis mindkét objektumunk egyedi, mindegyiknek van identitása.

Objektumdiagram

A UML objektumdiagramon egy objektum jelölése egy kettéosztott téglalap, melynek felső részébe az objektum azonosítója és típusa (osztály, lásd alább) kerül azonosító : típus formában, alsó részébe pedig az attribútumai és azok értékei vannak felsorolva egymás alatt, attribútum = érték alakban. Az objektumdiagram a rendszerben egy adott pillanatban létező objektumokat és azok aktuális állapotát mutatja.

SDLC SDLC
Objektumdiagram példák

Egy későbbi időpontban azután ugyanezen objektumok állapota változhat.

SDLC SDLC
Objektumdiagram példák

Diagram példák (állapot és viselkedés)

Nézzük a "kutyus" objektumunkat:

  • A neve "Buksi".
  • A színe barna.
  • És hogy éhes-e? Igen.

SDLC
A kutyusunk ábrázolása (egy korábbi időpillanatban).

Ez a kutyus objektumunk pillanatnyi állapota. Etessük meg a kutyust, ami szekvenciadiagramon így nézni:

SDLC
A "kutyusunk eszik" ábrázolása.

Akkor a korábban leírtak alapján (miszerint az eszik() viselkedés eredménye, hogy utána a kutya már nem lesz éhes) a kutyusunk állapota megváltozik:

SDLC
A kutyusunk ábrázolása (egy későbbi időpillanatban).

Diagram példák (identitás)

Nézzük a következő két objektumunkat:

SDLC SDLC
Két objektum azonos állapottal.

Ha azt nézzük, a két "Buksi" nevű fehér színű jóllakott objektumunkat az állapotuk alapján nem tudjuk megkülönböztetni. Ugyanakkor a "két objektumot nem tudjuk megkülönböztetni" mondatban benne is van a lényeg, hogy ez két külön objektum. Ez az identitás; nem (feltétlenül) tudom megmondani, hogy melyik melyik, de azt látom, hogy kettő van belőle: egyik kutya, másik eb.

Osztály

Azok az objektumok, melyeknek

  • a lehetséges állapotai (az állapottere, az attribútumaik, de nem feltétlenül azok értéke is),
  • más objektumokkal való lehetséges kapcsolataik, és
  • a viselkedésük (vagyis az, hogy milyen eseményekre hogyan, milyen viselkedésminta szerint reagálhatnak)

megegyezik, egyazon osztályba tartoznak. Az osztály tulajdonképpen egy minta az ilyen típusú objektumokhoz: megadja, hogy milyen attribútumaik, kapcsolataik (később) és operációk (a milyen és hogyan is) vannak. Az objektumok az osztály példányai, az osztály az objektumok típusa.

Osztály példa

Az előbbi példát folytatva, a kutyus, kutya, eb objektumaink típusa a Kutya osztály lehetne. A kutyák az alábbi tulajdonságokkal rendelkeznek:

  • Név (nev), ami egy sztring (a mi kutyusunké éppen "Buksi").
  • Szín (szin), ami egy Color típusú érték, (a mi kutyusunké éppen barna).
  • Éhes-e (ehes), ami egy logikai érték (a mi kutyusunk esetében ez időben változó).

Továbbá, a kutyáinknak volt háromféle viselkedése/viselkedésmintája:

  • Alvás (alszik()), aminek hatására a kutya objektum elalszik, ébredéskor pedig éhes lesz.
  • Evés (eszik()), aminek hatására a kutyának elmúlik az éhsége, vagyis az ehes attribútumának értéke hamis lesz.
  • Ugatás (ugat()), ami a modellünk szerint nem fogja megváltoztatni a kutya objektumaink állapotát.

Osztálydiagram

A UML osztálydiagramon egy osztály jelölése egy három részre osztott téglalap, melynek felső részébe az osztály neve kerül, középső részében az attribútumai és azok típusai vannak felsorolva egymás alatt attribútum : típus alakban, alsó részében pedig az operációi (metódusai) találhatók. Utóbbiakat részletességtől függően csak névvel metódus() alakban, vagy teljes szignatúrával, paramétereket és visszatérési érték típusát is definiálva, pl. metódus(par₁ : típus₁, par₂ : típus₂) : típus alakban adhatjuk meg.

SDLC
Osztálydiagram példa

Osztálydiagram példa

A modellezendő rendszerünkben szereplő Kutya osztály az alábbi tulajdonságokkal rendelkezik:

  • nev, ami egy sztring.
  • szin, ami egy Color típusú érték.
  • ehes, ami egy logikai érték.

Továbbá, a kutyusunknak volt háromféle viselkedése/viselkedésmintája:

  • alszik(), aminek hatására a kutya objektum éhes lesz.
  • eszik(), aminek hatására a kutyának elmúlik az éhsége.
  • ugat(), ami a modellünk szerint nem fogja megváltoztatni az objektum állapotát.

Osztálydiagramon meg tudjuk adni az attribútumokat és az elérhető viselkedéseket, de magát a viselkedésmintát nem:

SDLC
Osztálydiagram példa

Objektumok/Oszályok kapcsolatai

Egyes objektumok között különféle kapcsolatok lehetnek, ezeket a lehetséges kapcsolatokat is az osztályok definiálják. Ha két objektum között van közvetlen kapcsolat, akkor (legalább az egyik irányban) látják, ismerik egymást, meg tudják szólítani a másik objektumot. A kapcsolatoknak különböző jellemzőik lehetnek, úgy mint név, irány, szerep, multiplicitás, stb.

Asszociáció

A "leggyengébb" kapcsolat az asszociáció. Itt valóban csak annyiról van szó, hogy (legalább) az egyik objektum ismeri a másikat, tud róla. Egészen pontosan, ha két osztály között asszociáció van, akkor az adott osztályok egyes objektumai kapcsolatban lehetnek egymással.

Asszociáció példa

Ha a korábbi modellünket például kiegészítenénk egy Macska osztállyal, a Kutya osztályt pedig egy megilyeszt(m:Macska): void operációval, akkor a Kutya és Macska osztályok közé behúzható lenne egy asszociáció mondjuk "megilyesztette" néven.

Az asszociáció jele egy vonal a két osztály között.

Aggregáció/kompozíció

Az aggregáció és kompozíció ("gyengébb" és "erősebb") tartalmazási, rész-egész kapcsolatot fejez ki. Ilyenkor az egyik osztály objektumai valamilyen formában tartalmazhatják a másik osztály objektumait.

Aggregáció esetén ez lehet egy osztott vagy közös birtoklás (egy konkrét tartalmazott objektum több tartalmazó objektumban is szerepelhet egyszerre), a tartalmazott objektumok gyakran külön is elérhetők és akár tartalmazó objektum nélkül is létezhetnek.

Az aggregáció jele egy vonal, amely a tartalmazó oldalon egy üres rombusszal kapcsolódik a tartalmazó osztályhoz.

SDLC
Aggregáció jelölése

Kompozíció esetén a tartalmazás általában kizárólagos, a tartalmazott objektumot gyakran csak a tartalmazó objektumon keresztül lehet elérni és manipulálni (direktben nem), és tartalmazott objektumok nem igazán létezhetnek önmagukban, őket tartalmazó objektumokon kívül.

A kompozíció jele egy vonal, amely a tartalmazó oldalon egy teli rombusszal kapcsolódik a tartalmazó osztályhoz.

SDLC
Kompozíció jelölése

Aggregáció/Kompozíció

Az előző modellünket kiegészíthetjük egy Ember osztállyal, amely aggregációval "birtokolhatna" Kutya objektumokat. Ez a kapcsolat inkább aggregáció mint kompozíció lenne, hiszen egy kutya akkor is létezik, ha nincs gazdája (de a modelltől, annak céljától függően a kompozíció sem teljesen kizárható).

SDLC
Kompozíció jelölése

Kapcsolatok tulajdonságai

Az asszociáció/aggregáció/kompozíció kapcsolatoknak lehetnek tulajdonságaik, amelyeket a diagramon a vonalon, annak csatlakozási pontjain jelölünk.

A vonal közepén általában fel szokás tüntetni a kapcsolat értelmezését, és a név előtt ◀ vagy a név után ▶ jellel jelölni az "olvasási irány"-t. Utóbbinak angol nyelven sokkal nagyobb kifejezőereje van a kötött szórend miatt.

Olvasási irány

Az angol nyelvben a szórend kötött, így az "A teaches▶ B" a megadott olvasási irányban "A teaches B", az "A ◀teaches B" pedig "B teaches A" értelmet nyer, egyértelmű az alany és a tárgy. Magyar nyelven ezzel szemben ragok vannak, maga a szósorrend nem sokat jelent: az "A tanítja▶ B" egyaránt felfogható "A tanítja B-t" és "A-t tanítja B"-ként is. De ha egy adott diagramon megegyezünk pl. az alany-állítmány-tárgy szósorrend használatában, akkor egyértelművé tehetjük a jelölés értelmezését.

Lehet továbbá multiplicitást is jelölni a kapcsolat minkét oldalán. Ilyenkor a kapcsolatot jelölő vonal egyik vége mellé az osztály és a vonal találkozási pontjának közelébe írjuk a multiplicitást. Ez azt jelzi, hogy a kapcsolat másik végén lévő osztály egy adott objektumához ennek az osztálynak (ami mellé a multiplizitást írtuk) hány objektuma kapcsolódhat egy időben. Ha a multiplicitást egyetlen n számmal jelöltük, akkor n darab, ha egy m..n intervallummal, akkor legalább m és legfeljebb n. A számok helyett használhatjuk a * jelölést, ami a "tetszőleges"-et jelenti, így a "legalább m" jelölése az m..* lesz. Egy adott kapcsolat mindkét végén lehet egyszerre multiplicitás jelölő, ilyenkor ezek külön-külön értelmezendők.

Kapcsolatok tulajdonságai példa

Az előző modellünkben az Ember és Kutya közötti kapcsolat neve "gazgája", multiplicitása az Ember oldalán 0..1, a Kutya oldalán * lehetne. Ez azt jelentené, hogy egy Kutya objektumhoz 0 vagy 1 gazda objektum tartozna, egy Ember objektum viszont akárhány Kutya objektumnak gazdája lehetne.

SDLC
Kompozíció jelölése

Asszociáció, Aggregáció és Kompozíció

Az alábbi ábrán a Kurzus és az Oktato között asszociáció van, mejnek jelentése, hogy az "Okato oktat egy Kurzust". Egy Kurzushoz pontosan egy Oktato tartozik, de egy Oktato akárhány Kurzust oktathat (akár egyet sem). Minden oktató része továbbá pontosan egy Tanszeknek, és egy Tanszeknek akárhány Oktatoja lehet. A modell szerint akár olyan Tanszek is elképzelhető, aminek nincs egyetlen Oktatoja sem.

SDLC
Kapcsolatok osztálydiagramokon

Öröklődés

Az öröklődés az OOP egyik erős eszköze. Az öröklődés során van egy ős/szülő osztályunk és egy leszármazott/gyermek osztályunk. A leszármazott "örökli" az ősosztály összes attrubútumát és operációját, de bővítheti/módosíthatja is azokat. Konkrétan, a leszármazott bővítheti az ős attribútumait és metódusait, azaz hozzáadhat újakat, illetve felüldefiniálhatja már (az ős-ben is) létező operációk működését (a viselkedési mintát). Így a leszármazott típusú objektum egyrészt mindent tud, amit az ős típusú objektumok, de azoknál többet is tudhat, és másként viselkedhet (ez utóbbi a (dinamikus) polimorfizmus alapja). Egy szülő osztályból akárhány gyermek osztály származtatható, és elméletben egy gyermek osztálynak akárhány (közvetlen) szülő osztálya lehet, ez utóbbit nevezzük többszörös öröklődésnek. (A többszörös öröklődés viszont felvet bizonyos kérdéseket (azonos nevű attribútumok, "gyémánt" öröklődés), ami miatt például Java-ban nincs is megengedve.) Az öröklődési láncok adják az osztályhierarchiát (összességében általánosságban egy körmentes gráfot alkotva). Ebben a hierarchiában az ősök felé indulva általánosítiunk, a leszármazottak felé specializálunk.

Az öröklődés jele egy üres derékszögű egyenlő szárú háromszög fejjel ellátott nyíl, amely összeköti a két osztályt, és a leszármazott felől az ős irányába mutat. Az öröklődés kapcsolatnak nincsenek tulajdonságai.

SDLC
Öröklődés jelölése

Az alábbi példán a Felhasznalo osztálynak két leszármazottja van, az Oktato és a Hallgato. Minden Oktato és Hallgato Felhasznalo is egyben, van pl. azonosítója és jelszava, tehát ilyen módon a Felhasznaloi tulajdonságaikban egyeznek. De az is látszik, hogy különböznek egymástól, más-más dolgokat tudnak például megtenni. Az Oktatonak pl. lehetnek oktatott kurzusai, és kiírhat vizsgákat, míg a Hallgatonak felvett órái vannak és jelentkezhet a vizsgákra.

SDLC
Több leszármazott egyetlen ősosztályból

Öröklődés példa

Az előző modellünkben a Kutya és Macska osztályoknak lehetne egy közös Állat őse. Mivel minden állatnak van neve, színe és lehet éhes, ezek az attribútumok az Állat osztályban lennének definiálva, és így a Macskák is örökölnék őket. Az eszik() és alszik() operációkat szintén át lehetne vinni a közös ősbe, de az ugat() maradna a Kutya osztályban (legalábbis tudtommal a macskák nyávognak, nem ugatnak). Továbbá, ha úgy ítéljük meg, akkor mondjuk az eszik() operáció által az Állat osztályban definiált viselkedésmintát mind a Kutya, mind a Macska osztályban felüldefiniálhatjuk. Például úgy, hogy a Macskák evés után alszanak egyet.

Többszörös öröklődés

A többszörös öröklődéssel az egyik technikai probléma az, ha a több szülőtől ugyanolyan nevű, de más eredetű attribútumot vagy operációt öröklünk. Ilyenkor az azonos nevű elemek egyértelmű beazonosítása nehézkes és bonyolult lehet. És még ezen is túltesz az úgynevezett "gyémánt" öröklődés, amikor egy közös őstől származó két osztálynak van egy közös leszármazottja. Ilyenkor azt kellene eldönteni, hogy a közös ősben definiált metódus vagy attribútum a közös leszármazottban két azonos nevű, de különböző dolog-e (mint például a Gépjármű-ből származó motor attribútum, ami a Benzines és Elektromos osztályokon keresztül öröklődik a Hibrid osztályba, amiben két külön motor lesz, egy benzines, és egy elektromos), vagy egyetlen, tulajdonképpen a "nagyszülőtől" (közös őstől) egyenesen örökölt valami (mint például a Jármű kormánykerék attribútuma, amiből a VíziJármű és KözútiJármű közvetítésével is csak egy darab van a KétéltűJármű osztályban).

SDLC
Gyémánt öröklődés

Vannak programozási nyelvek, pl. a C++, ahol megoldott a többszörös öröklődés, és a gyémánt öröklődés eldöntésére is van mechanizmus, de a Java nyelv alkotói (jogosan) úgy gondolták, hogy ez jóval bonyolultabbá teszi a nyelvet, mint amennyi hasznot hoz, így nem engedték. De azért van mód valami többszörös öröklődéshez hasonló dolog megvalósítására ott is.

Csomag

Egy nagyobb rendszerben rengeteg osztályunk lehet, akár több ezer. Nyilvánvaló, hogy ha ezek "csak úgy vannak", a rendszerünk, a modellünk átláthatatlan lesz. A csomagok segítségével rendszerezni, csoportosítani tudjuk az osztályainkat. Ez a csoportosítás ráadásul hierarchikus lehet (egy csomagban nem csak osztályok, de újabb (al)csomagok is lehetnek. (Mintha az osztályaink fájlok, a csomagjaink pedig könyvtárak lennének.)

Minden csomag tartalmazhat interfész és implementációs osztályokat. Egy csomag interfész (publikus, nyilvános) osztályait bárki láthatja, használhatja, a csomagon kívülről, másik csomagból. A csomag implementációs (privát, belső) osztályait csak a csomagon belül tudjuk használni.

A csomag jelölése az osztálydiagramokon mappaszerű: egy tégkakap alakú keret, melynek bal felső sarkákoz kívülre a keret tetején egy téglalap alakú cimkét illesztünk, ami a csomag nevét tartalmazza.

SDLC
Csomag jelölése

Csomag példa

Az előző modellünkben a Kutya, Macska, Állat és Ember osztályok mind Élőlények, így bekerülhetnek egy ilyen csomagba, míg a Tűzcsap vagy Lámpaoszlop egy Tárgy nevű csomagba kerülhetne.


Utolsó frissítés: 2023-02-15 08:49:35