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:

  • Telepítési nézet:

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.

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 "Buksi".
  • A színe, ami barna.
  • Egy jellemző, hogy éhes-e, ami igen vagy nem lehet.

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.

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 objektumunk (objektumaink) típusa a Kutya osztály lehetne. Minden Kutya objektumnak lenne

  • neve, ami egy sztring,
  • színe, ami egy felsorolás típus,
  • éhes-e attribútuma, ami egy logikai érték.

Ezen felül rendelkeznének az alszik(), eszik() és ugat() operációkkal, amik a fentebb leírt módokon működnének (azaz amely ingerekre a Kutya objektumok egységesen, a fentiek szerint reagálnának).

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.

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

Aggregáció/kompozíció

Öröklődés

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.


Utolsó frissítés: 2022-02-21 16:20:54