rendszerfejlesztés - itcluster.hu · a dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a...

21
Rendszerfejlesztés Konstantinusz Kft. © 2009

Upload: others

Post on 31-Oct-2019

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Rendszerfejlesztés

Konstantinusz Kft.

© 2009

Page 2: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

TartalomjegyzékElőszó .................................................................................................................................. 3

Bevezetés .............................................................................................................................4

A specifikáció ................................................................................................................................4

UML .................................................................................................................................... 5

Osztályok .............................................................................................................................5

1. Közös ős .....................................................................................................................................6

2. Öröklődés ...................................................................................................................................6

3. Strukturális kapcsolat .................................................................................................................7

4. Állapotok ...................................................................................................................................7

5. Közös interfész ..........................................................................................................................8

Struktúra ..............................................................................................................................9

Asszociáció.....................................................................................................................................9

Aggregáció....................................................................................................................................10

Kompozíció...................................................................................................................................11

Multiplicitás (számosság megkötés) ............................................................................................11

Szekvencia .........................................................................................................................13

Az újrafelhasználhatóság és hordozhatóság elve: ........................................................................14

Procedurális absztrakció: .............................................................................................................14

Információ elrejtés elve: ..............................................................................................................15

Állapot ...............................................................................................................................19

Utószó ................................................................................................................................21

Page 3: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Előszó

Sokszor találkozhatunk vele, hogy a szoftverfejlesztés világában megkülönböztetve beszélnek többféle munkáról. Programozó, rendszerfejlesztő, szoftvermérnök, stb. Mi a különbség? Miért mondják, hogy valaki „csak” programozó? Mi a különbség programozás és szoftverfejlesztés között?

A válasz abban rejlik, hogy egy szoftver kifejlesztésének talán legfontosabb szakaszai nem azok, amikor az ember programkódot ír. Sőt, van hogy időben sem az teszi ki egy szoftver elkészítésének a nagyobb részét. A munkának a legfontosabb része még csak nem is a számítógép előtt ülve zajlik. Ahogy egy ház felépítésének is a legfontosabb részei a tervek, úgy egy szoftver eredményességéről is a munkának ezen szakaszai döntenek leginkább. Ugyanúgy, ahogy egy építészeti tervnek, tervrajznak is megvannak a módszerei, a formalizmusai, ugyanúgy a szoftverfejlesztésnek is.

Ez a tanulmány azoknak szól, akik programozóként már rendelkeznek alapos előképzettséggel, tapasztalattal, az objektum-orientált programozás eszközeit magabiztosan használják, viszont szeretnének továbblépni a programozási szintről, de nem tudják hol kezdjék, vagy túl magas szintű tananyagokhoz jutottak csak hozzá, amik nem kapcsolódtak elég kézzel foghatóan a gyakorlati, programozási szinthez.

Ez a tanulmány ezen a ponton szeretné felvenni a fonalat. Bemutatni a szoftvertervezés alapvető eszközeit, módszereit, de csak azokat, amik még nem túl távoliak a megszokott, gyakorlati, programozási világtól. Továbbá fontos az is, hogy az olvasó értse, hogy az itt említett elméleti dolgok miként képződnek le gyakorlati szintre és válnak kézzel fogható programkóddá.

Page 4: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Bevezetés

Szoftverfejlesztés az életben sokféle összetevőt foglal magába, nem csak a programozást, vagy a program megtervezését. Természetesen nagy mértékben megszabják az anyagi, vagy technikai korlátok is, de szoftverfejlesztő / programozóként ez többnyire nem a mi dolgunk. Amik viszont nagyon is érint minket, azok a megrendelő igényei. Hogy miért itt kezdődik a mi munkánk? Mert a mi dolgunk az, hogy ezeknek az igényeknek betűről betűre eleget tegyünk, és ehhez nagyon tudatosan kell tervezni a szoftverünket.

A specifikáció

Így kezdődik minden szoftver élete. Ideális esetben előáll egy dokumentum, ami precízen tartalmazza minden részletét a szoftver működésének, és kinézetének. Így aztán a fejlesztés legelső fázisában az lesz a dolgunk, hogy a szabad szövegként megfogalmazott specifikációból kihámozzuk, hogy mik lesznek a szoftverünk összetevői, amit a számítógép is megért, és hogyan kell, hogy működjenek, hogy életre hívják azt, amit a specifikáció meghatároz.

A világ objektumokból áll. Az objektum orientált programozás a mai napig a legjobbnak bizonyult módszer a világ bonyolult rendszereinek a leírására. Elegáns eszközrendszer, de mindez semmit sem ér, ha rosszul képezzük le a valós világ (a specifikáció) rendszereit, folyamatait, hiszen épp ez a munkánk lényege. Veszem a valós világnak egy részét, és modellezem objektumokkal, objektumok rendszerével.

Objektum modell, és objektum modell között ég és föld lehet a különbség, ahogy programozó és programozó között is, program és program közt is. Szükségünk van módszerekre, amivel a specifikációban leírtakat helyes módot képezzük le egy objektum modellre.

A módszer, amiről a továbbiakban szó lesz, az UML (Unified Modeling Language) nevet kapta, ami egyben egy rendszer modellezési koncepció is, ami az objektum orientált elvekre épül, OO felfogásban gondolkodik, másrészt egy formalizmust ad, amivel elkészíthetjük a szoftverünk „tervrajzát”.

Ebben a tanulmányban inkább a koncepcionális, illetve módszerbeli elvekre tesszük a hangsúlyt, és csak kevésbé magára a formalizmusra. Ha valaki szeretné részleteiben megismerni az UML-t, akkor javaslom, hogy a megfelelő szakirodalomból tanulja azt meg.

Page 5: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

UML

Az UML-nek azon része ami itt most érdekelni fog minket, négy terület lesz:

OsztályokStatikus struktúraSzekvencia (folyamatok)Állapotok

Ezeket mind úgy képzelhetjük el, mint egy-egy nézet a tervrajzon az adott tárgyról. Mindegyik egy más-más oldalát elemzi, írja le a tárgynak, így mindből együtt összeáll egy teljes kép.Mint tudjuk, egy rendszer áll adatmodellből és viselkedés-, vagy más néven eljárásmodellből. Az OO elv kimondja, hogy ez a két réteg nem különválasztható. Objektumok fogják össze egy-egy elemét az adat-, illetve viselkedésmodellnek.

Ez a négy szempont leírja, hogy az objektumok milyen kapcsolatban állnak egymással, milyen adatokat „tárolnak”, és milyen folyamatokban hogyan vesznek részt.

Nagyon fontos hogy ez a szintje a tervezésnek absztrakt, koncepcionális szint. Az objektumaink nem egy valódi nyelv valódi objektumai. A kapcsolatok, állapotok nem feltételeznek semmilyen nyelvi reprezentációt ezen a szinten. Tehát ne az járjon a fejünkben, hogy hogyan is jelennek meg dolgok C++-ban, PHP-ban, Java-ban, vagy akármilyen konkrét programozási nyelvben leírva. Itt még minden független a nyelvtől, és az implementációs megoldásoktól (kivétel bizonyos nyelvi korlátok mint pl. többszörös öröklődés, stb.)! Ezt nagyon fontos megérteni, mert erre a szemléletváltásra szükség van ahhoz, hogy az ember elszakadjon a kódírástól, és magasabb szintű elvek szerint tudja megtervezni a rendszerének a felépítését.

Osztályok

Az első dolgunk, amit ki kell hámozni a specifikációból, hogy milyen „elemekből” áll a leendő rendszer. Ezek, a most még elemeknek nevezett dolgok lesznek később az osztályaink, de egyelőre még nem tudjuk pontosan, hogy milyen osztályokra is lesz szükségünk, és ezek milyen kapcsolatban állnak majd egymással.

Először is, a specifikáció alapján készíteni kell egy „objektum” listát. Ezek még nem programozási értelemben vett objektumok, csak valamilyen elemek. Ebben a fázisban még nem foglalkozunk a köztük lévő összefüggésekkel, azzal se hogy ha pl. két dolog valójában ugyanaz, vagy hogy egy dolgok igazából két másikat takar.

Az objektumlista után kell ezeket rendszereznünk, osztályokat alkotni belőlük amik valamilyen kapcsolatban lesznek, lehetnek egymással.

Fontos rögtön az elején megjegyezni, hogy egyáltalán nem egyértelmű a specifikációban olvasható „objektumok” alapján, hogy hogyan is fog kinézni a tényleges objektum modell. Könnyen lehet, hogy az ami egy dolognak tűnt, szétbomlik több osztályra is. Lehet, hogy bizonyos dolgok egyesülnek egy osztályként, vagy előtűnnek olyan osztályok amik semmilyen módon nem párosíthatók semmihez ami a szövegben olvasható.

Kiderülhet, hogy két dolog egymásból származik, vagy hogy egy új, közös ősosztályból érdemes őket származtatni, vagy külön osztályok lesznek valamilyen kapcsolattal, vagy ugyanaz az osztály lesz, csak két különböző állapottal.

Page 6: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Szeretnék itt most néhány nagyon gyakori, tipikus példát bemutatni, és módszereket, „recepteket” rá, hogy hogyan lehet ezeket könnyen felismerni, és implementációban hogyan jelennek majd meg. Ezekkel egy „kezdő” rendszerfejlesztő is viszonylag hamar el tud majd igazodni egy nem túl bonyolult rendszer megtervezésében.

1. Közös ős

Ha két dolognak sok közös tulajdonsága van, és a viselkedésükben is sok a közös, viszont ezek mellett mindkettőnek vannak egyedi tulajdonságaik is, és egy dolog nem rendelkezhet egyszerre mindkettőnek minden tulajdonságával, akkor ez valószínűleg az az eset, amikor az egy ősosztályból kell származnia két külön osztálynak. Az ősosztály magába foglalja a közös részt, a két alosztály pedig kibővíti azt az egyedi tulajdonságaikkal.

Például: Veréb és Galamb. Ezek a Madár ősosztályból származnának, hiszen nem rendelkezhet valami egyszerre a galamb és a veréb tulajdonságaival is. A második legfontosabb meghatározó jellemzője ennek az esetnek az, hogy ez a viszony időben nem változhat meg, tehát a viszony statikus. A galamb nem változhat verébbé, és fordítva sem.

Tehát röviden:

• Közös, kiemelhető jellemzők • Egy dolog egyszerre nem lehet mind a kettő • Időben nem változhat a viszony

Ha bármi ezekből nem teljesül, akkor nem ez a jó megoldás.

2. Öröklődés

Ha egyik dolog rendelkezik a másiknak minden tulajdonságával, plusz még többel is, vagy egy-két dolgot máshogy csinál mint a másik, akkor ezek lehet hogy egymásból származnak. Az alosztály újabb tulajdonságokat is bevezethet, vagy valamilyen módon kibővíti, módosítja a szülőnek a tulajdonságait.

Például: szék és gurulós szék. A gurulós szék is mindent tud amit a sima szék, csak még gurul is. Természetesen ez a viszony is statikus, tehát időben nem változhat. Egy sima szék nem változhat át gurulós székké.

Röviden:

• Egyik rendelkezik a másik minden tulajdonságával • Időben nem változhat a viszony

A fenti két eset, mint láttuk, akkor állja meg a helyét, ha a viszony a vizsgált dolgok között statikus, vagyis sose változik.

Page 7: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Vegyük példának azt, hogy ügyfél és dolgozó. Ezekkel akarunk foglalkozni egy rendszeren belül. Látszik, hogy sok közös tulajdonságuk van (név, lakcím, telefon, szig., taj, stb.), és mindkettőnek vannak egyedi tulajdonságai is (ügyfélnek bónuszpontjai, dolgozó munkaköre, stb.). Ezek alapján lehetne a közös ősük egy Személy osztály, ami a közös részt valósítaná meg. Csakhogy, egy személy lehet egyszerre dolgozó és ügyfél is, sőt, időben is változhat, hogy pl. valaki dolgozó-e vagy sem. Tehát az első két eset nem teljesül.Itt újabb megoldások merülnek fel.

3. Strukturális kapcsolat

A személy, az ügyfél és a dolgozó külön objektumok, nem származnak egymásból, hanem más kapcsolatban lesznek egymással (ebben az esetben a személyhez kapcsolódhatna az ügyfél és a dolgozó is). Ezzel teljesül, hogy lehet valaki egyszerre ügyfél és dolgozó is, illetve időben is változhat ez az állapot. Ezen felül a dolgozó és a személy saját tulajdonságai, és viselkedése jól el is van különítve a személytől, így mind a három osztályban csak az van ami a „saját dolguk”.

Ebben a modellben, igaz hogy valójában 3 különálló objektumról van szó, mégis ezek számunkra logikailag egy egységet képeznek.

Röviden:

• A vizsgált dolog több külön objektumra bomlik • Egy dolog rendelkezhet egyszerre minden tulajdonsággal • Időben változhat

4. Állapotok

A különbözőnek látszó dolgok valójában egyetlen objektumnak más-más állapotai. Például termék és akciós termék modellezéséhez elég ha egy osztály létezik, a termék, és annak vannak állapotai (amit pl. egy attribútum különböző értekei reprezentálnak), hogy akciós-e vagy sem. Ezen állapotok alapján a terméknek más lesz az ára (pl. árengedményt kap), és esetleg másként is viselkedik bizonyos helyzetekben. Teljesül az is, hogy időben „átalakulhat” termék és akciós termék egymásba. Ez a megoldás akkor jellemző, ha a két dolog olyan nagyon hasonló, hogy szinte ugyanazok, és nincs nagy viselkedésbeli különbség.

Röviden:

• Egy objektum csak egy állapotban lehet egyszerre • Időben változhat • Minden tulajdonság közös minden állapotban

Ez eset nem teljesül, ha a vizsgált dolgoknak vannak egyedi viselkedéseik vagy tulajdonságaik.

A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része, de saját tulajdonságaik is vannak, amik nagyon egyediek, és egy dolog lehet egyszerre ügyfél is, dolgozó is, vagy egyik se, és ez időben is változhat.

Page 8: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

5. Közös interfész

Ha két különböző osztálynak van közös viselkedése, és ezt a közös viselkedést nem tudjuk kiemelni egy ősosztályba (vagy nem lehet, mert már van ősosztályuk, de abba sem tartozik ez a közös viselkedés), akkor lehet használni az „interfész-objektum” módszert. Ez azt jelenti, hogy a közös rész egy külön osztály lesz, amiből egy példányt le tudunk kérdezni ahhoz a célobjektumhoz, amin használni akarjuk. Tehát a célobjektumunk visszaad egy objektumot, ami tartalmazza a szóban forgó funkciókat, és valamilyen módon az is beállítódik, hogy ez az interfész-objektum a célobjektumunkhoz kötődik.

Ez olyan, mintha a számítógépünkhöz alap helyzetben nem lenne billentyűzet amivel irányíthatom, hanem egy gomb megnyomásával „készítene” a gép egyet, amivel tudnánk a gépet irányítani. Aztán ha már nem kell, eldobjuk a billentyűzetet, és később ha megint kell, a gép megint gyárt nekünk másikat.

Ugyanezt tenné egy objektum is. Például egy metódusán keresztül lekérdezhetném ezt az interfész-objektumot, és annak a metódusait hívva, az eredeti objektumot tudnám manipulálni.

Az interfész-objektum konkrét megvalósítású metódusokat tartalmazhat (ezért is nem elég valódi interfésszel megoldani), és ezek a metódusok a célobjektumot manipulálják, vagy adnak vissza róla információkat.

Gyakran lehet látni ezt a megoldás enumerátoroknál. Ha van például egy lista objektumom, és szeretném bejárni a lista elemeit, akkor az objektumnak meghívom például a getEnumerator() nevű metódusát, ami létrehozza, és visszaadja nekem az enumerátort (ezt a mi interfész-objektumunk). Ezután az enumerátor objektumom mindig a lista egy elemére fog mutatni, amit lekérdezhetek például egy getElement() nevű metóduson keresztül, és léptethetem a következő elemre egy next() nevű metódussal. Ha végeztem, az enumerátort eldobhatom.

Ez a módszer azért lehet célszerű, ahelyett hogy a lista objektum metódusait hívogatom közvetlenül, mert sok más osztályt is lehet enumerálni (és mindet másfajta módon kell), és ezeknek az enumerátorai így származhatnak egy közös ős-enumerátorból.

UML-ben egy osztályt a következőképpen jelölünk:

Egy dobozba írjuk felülre az osztály nevét, középső hasábba az attribútumokat, alsóba pedig a metódusokat. A metódusok és az attribútumok előtt szerepel a láthatóság szimbóluma: + publikus, – privát, # védett. Az adott metódus vagy attribútum után kettősponttal elválasztva írjuk a típusát (metódus esetén a visszatérési érték típusa). Az osztálymetódusok alá vannak húzva. Metódusok paraméterei név: típus formában vannak ábrázolva, és vesszővel vannak elválasztva ha több is van.

Page 9: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Öröklődést két osztály között nyíllal jelöljük, aminek a feje háromszög alakú, és üres. A nyíl mindig az alosztálytól mutat az ősosztály felé:

Ezeknél több részletet is ábrázolhatunk ezeken a diagramokon, de nekünk nem célunk most az UML formalizmusának részletes megismerése, most csak a legalapvetőbb dolgokra térünk ki, és inkább tervezés koncepcionális és módszeri oldalára koncentrálunk.

Struktúra

Miután meghatároztuk, hogy milyen osztályai lesznek a rendszerünknek, fel kell térképeznünk, hogy ezek milyen struktúrális kapcsolatban állnak egymással. Az öröklődés nem struktúrális kapcsolat, azt az előző fázis tárgyalta.

Kapcsolatot legtágabb értelemben kell venni. Kapcsolatnak számít ha pl. két dolog rész-egész viszonyban van egymással (pl. az asztal és a négy lába), de kapcsolat az is ha pl. egyik ember ismeri a másikat.

Kapcsolatoknak ezért több fajtája is lesz, a leglazábbtól a legszorosabbig. Amiért fontosak lesznek a kapcsolatok az az, hogy különböző viselkedéssel járnak a különböző fajta kapcsolatok. Programozási szempontból ez lesz a lényeges része ennek a témának. Ezért fontos a kapcsolatok alapos és pontos feltérképezése.

Mit értünk viselkedések alatt? Például rész-egész viszont esetén elvárjuk, hogy a szülőobjektumhoz tartozó részek is törlődjenek ha törlöm a szülőt. Például ha van egy ügyfél objektumom, és kapcsolódik hozzá egy adatlap objektum, akkor elvárható, hogy ha az ügyfelet törlöm, akkor az adatlapja is törlődjön, hiszen annak nincs értelme önmagában megmaradnia.

Kapcsolatoknak 3 fő típusa van:

Asszociáció

Ez a legegyszerűbb, leglazább kapcsolat típus. A valós életben ilyen kapcsolat lenne pl. a barátság, vagy az ismeretség. Egyik ember barátja a másiknak, vagy ismeri a másikat (fordítva nem feltétlen igaz). Ez a kapcsolat típus semmilyen komolyabb megkötéssel, kötelezettséggel nem jár. Egyszerűen csak számon tartja egyik ember a másikat valamilyen szempont szerint.

Page 10: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Fontos viszont, hogy a kapcsolatnak van iránya. Ha én ismerek valakit, akkor én „asszociálok” a másik emberre, de fordítva ez nem igaz, ő nem feltétlen ismer engem. Viszont ennek ellenére felteheti a kérdést hogy „ki ismer engem?”, és megkaphatja rá a választ, hogy ki asszociál rá. De a lényeg, hogy a kettő közt különbség van. Ha én azt a kérdést teszem fel hogy „kit ismerek?” akkor megkapom válaszként a másik embert, akit ismerek, de ez nem jelenti azt, hogy erről a másik ember is tud. Továbbá, ha ő teszi fel a kérdést, hogy „ki ismer engem?”, akkor megkapja a választ, hogy én ismerem őt, viszont ettől én még mindig nem vagyok az ő barátja, tehát a kapcsolat még mindig egyoldalú.

Asszociációnál tehát a legfontosabb feladatunk az irány helyes megválasztása (és persze annak felismerése, hogy egyáltalán asszociációról van-e szó).

Aggregáció

Az aggregáció szorosabb kapcsolat mint az asszociáció, szintén beszélhetünk irányról is. Az aggregációt fel lehet fogni egyfajta rész-egész, vagy birtokviszonyként is.Egy aggregáció két oldalán álló objektumot nevezzük szülőnek és gyermeknek. Ekkor azt mondjuk, hogy a gyermek aggregál a szülőhöz. A szorosság abban nyilvánul meg hogy a gyermek nem létezhet szülő nélkül (fordítva viszont nem igaz, a szülő létezhet gyermek nélkül). Ez a megszorítás már speciális viselkedést is megkövetel a kapcsolatban résztvevő objektumoktól.

Először is, ha létrejön egy gyermek objektum, akkor azonnal ki kell épülnie a kapcsolatának a szülő felé, illetve a szülő megléte nélkül nem is jöhet létre. Ez az, amire a programozónak kell odafigyelnie, megvalósítani a gyermek objektum működését ilyen feltételekkel. A másik eset, ahol az aggregáció által megkövetelt viselkedés életbe lép, ha a szülő objektum törlődik. Mivel a gyermek nem létezhet szülő nélkül, és mivel az aggregáció egyfajta rész-egész viszonyt modellez, ezért a szülő törlésével értelmetlenné válik a gyermek létezése is, tehát szükségszerűen meg kell semmisíteni. Ez tehát a második dolog, amire egy programozónak oda kell figyelnie implementáláskor.

Aggregáció pontos felismeréséhez fontos, hogy a jó kérdést tegyük fel. A legtöbb ember itt el szokott kavarodni abban, hogy mi minek a része, és mi létezhet vagy nem létezhet más nélkül. Egyszerűen csak arra kell figyelni, hogy ha egy adott objektumot törölnék, akkor milyen más, vele kapcsolatban álló objektumokat kellene törölni. Például: „Ha törlök egy Ügyfél objektumot, törlődnek a hozzá tartozó Számla objektumok is?”. Nyilván névtelen számla nincs, tehát a válasz igen, vagyis az Ügyfél lesz a szülő, és hozzá aggregál a Számla.

A következő helyzet viszont félrevezető lehet: Tegyük fel, hogy van Vásárló, és neki Szállítási címe.

Tegyük fel, hogy egy vásárlónak több szállítási címe is lehet, viszont legalább egy mindig kell hogy legyen. Akkor most a vásárló nem létezhet szállítási cím nélkül, vagy a szállítási cím nem létezhet vásárló nélkül? Melyik aggregál melyikhez? Nos, rossz kérdést tettünk fel. A helyes kérdés: „Ha a vásárlót törlöm, akkor törlődnek a szállítási címei is?”. A válasz igen, hiszen személy szerint hozzá tartoznak. Viszont, ha azt kérdezem „Ha a szállítási címet törlöm akkor törlődik a vásárló is?”. A válasz pedig nyilván nem. Az, hogy a vásárló legalább egy szállítási címmel jöhet csak létre, illetve hogy az utolsó megmaradt szállítási címet már nem szabad törölni, egy másik fajta megszorítás lesz, erre később térünk ki.

Page 11: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Kompozíció

Ez a legszorosabb kapcsolat típus, ezt már mondhatjuk igazi rész-egész viszonynak is. Ebben az esetben a kompozícióban álló objektumok együtt építenek fel egy egységet, ami a részei nélkül már nem is lenne az ami. Ilyen például egy balta, ami áll a nyeléből, és a fejéből. Akármelyiket is vesszük el a kettő közül, a balta többé nem lesz balta. A valóságban persze szétszedhetjük, és össze is rakhatjuk bármikor, de a kompozíció épp az mondja ki, hogy ezt nem tehetjük meg.

Ha egyszer a baltát összeraktuk, akkor azt többé szét nem lehet szedni, megsemmisíteni is csak egyben lehet, vagy sehogy. Pontosan ennek a megvalósítása lesz a programozó feladata is, kompozícióban álló objektumok esetén. Mivel a kompozíció esetén is van a kapcsolatnak iránya, ezért kétféle gondolkodásmód lehet: ha a balta a szülő, és neki a gyermekei a feje és a nyele, akkor az egyik lehetséges megvalósítás, hogy a nyelet és a fejet nem lehet törölni, csak a baltát lehet, amivel együtt viszont megsemmisül a nyél és a fej is. A másik, hogy bármelyik elem törlése esetén törlődik az egész struktúra.

Fontos, hogy itt se tévesszen meg minket az a tény, hogy nem lehet szülő-gyermek viszonyban a gyermeket törölni. Ez nem csak azt jelenti, hogy a gyermekek számának van egy minimuma, mint a vásárló és a szállítási cím esetén, hanem ettől függetlenül sem lehet a gyermekeket törölni. Például képzeljünk el egy számlát. A számlához tartoznak fizetési módok, amik megmondják, hogy mivel fizettük, milyen összegben (pl. készpénz 5000 Ft, bankkártya 10 000 Ft, üdülési csekk 8000 Ft). Egyszerre több is lehet, és a számuk változó. A fizetési módok csak és kizárólag egy adott számlához tartoznak. Minimum egynek kell létrejönnie, viszont miután létrejöttek a számlával együtt, már elidegeníthetetlen részei a számlának, és nem lehet őket törölni, sőt, újat se lehet felvenni, és ez a számuktól teljesen független! Ez egy tipikus kompozíciós eset.

Multiplicitás (számosság megkötés)

A 3 fent említett kapcsolat típus mellett egy újabb megszorítási fajta is létezik, ez a multiplicitás. Ez azt szabja meg, hogy egy kapcsolatban hány objektum vehet rész egyik, illetve a másik oldaláról. Ennek lehet alsó, és felső határa is.

Gondoljunk a barát példára. Egy ember akárhány embert tarthat a barátjának, és őt is akárhányan tarthatják a barátjuknak. Egy embernek lehet, hogy egyetlen barátja sincs, és lehet, hogy egyetlen ember sem tartja barátjának. Ennek a kapcsolat típusnak mindkét oldalának a multiplicitása 0-tól végtelenig terjed. Ez egy tipikus „több a többhöz” kapcsolat.

Az ügyfél és a számla esetén már más a helyzet, hiszen egy ügyfélnek akárhány számlát állíthatunk ki, de minden számla pontosan egy ügyfélhez tartozhat csak. Ekkor azt mondjuk, hogy az ügyfél oldalán a multiplicitás pontosan 1, a számla oldalán pedig 0-tól végtelenig terjed. Ez egy tipikus "1 az n-hez" kapcsolat.

Balta és a feje esetén a kapcsolat mindkét oldalán pontosan 1 objektum szerepelhet, nem több, nem kevesebb. Ez az "1 az 1-hez " kapcsolat.

A számosság megkötések szintén programozói kötelezettségeket vonnak maguk után, ami alapvetően annyit jelent, hogy csak akkor lehet egy kapcsolathoz hozzáadni vagy elvenni belőle objektumot, ha a számossági megkötéseken belül maradunk.

Van viszont pár különlegesebb eset, amit külön érdemes említeni.

Page 12: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Ha például egy számlát szeretnék létrehozni, akkor a számlát úgy kell megvalósítani, hogy ne lehessen létrehozni ügyfél nélkül, hiszen a számosság megkötés szerint egy számlához pontosan egy ügyfél tartozik. Tehát a számlának meg kell követelnie azt, hogy „kapjon” egy ügyfelet a létrehozásához.

Szintén tipikus példa a vásárló és a szállítási cím esete, ahol kikötöttük, hogy szállítási címből legalább egynek lennie kell. Ez természetesen érvényes a vásárló létrejöttének a pillanatában is, tehát a vásárlónak is meg kell követelni a létrejöttéhez egy szállítási címet, vagy akár saját magának kell létrehoznia azt!

Most pedig lássuk a jelöléseket UML-ben.

Asszociációt egy hagyományos nyíl jelöli. A nyílra írjuk a kapcsolat megnevezését. A kapcsolat két végére írjuk a multiplicitási megszorításokat. Ha nincs megszorítás, akkor *-gal jelöljük, egyébként intervallumot adunk meg 0..5, 0..*, 1..10, stb. formában.

Ebben a példában egy személynek akárhány ismerőse lehet és egy személyt akárhányan ismerhetnek, tehát mindkét vége * lesz. Mivel itt osztályokat ábrázolunk, ezért az, hogy a nyíl visszafordul a kiindulási osztályba nem azt jelenti, hogy egy adott objektum példány önmagára hivatkozik, hanem csak annyit, hogy a kapcsolat két végén ugyanolyan osztályú objektumok állhatnak, vagyis személyek.

Dolgozó és munkakör esetén egy dolgozónak pontosan egy munkaköre van (legalábbis ebben a példában), így a munkakör oldalán 1-est látunk. Mivel több dolgozónak is lehet ugyanaz a munkaköre, vagy akár egyik dolgozóhoz se tartozik egy adott munkakör, ezért a dolgozó oldalán *-ot látunk, vagyis egy munkakörhöz akármennyi, vagy semennyi dolgozó tartozhat.

Aggregációt egy üres rombusz jelöli. A gyermektől mutat a szülő felé. A kapcsolat nevét, multiplicitását a szokásos módon jelöljük. Ebben a példában a vásárlóhoz aggregálhatnak számlák és címek. Egy számla csak egy vásárlóhoz tartozhat, viszont egy vásárlónak akárhány számlája is lehet, beleértve a nullát is. A címnél viszont egy érdekes helyzetet láthatunk. A Vásárló osztály a Cím osztállyal kétféle módon is kapcsolatban van. Ez nem azt jelenti, hogy ugyanaz a cím objektum kétféleképp aggregál a vásárlóhoz. Csak annyit jelent, hogy a lakcím és a postacím nevű kapcsolatok túloldalán Cím osztályú objektumok lehetnek. A kétféle kapcsolatnak az az értelme, hogy meg tudjuk különböztetni, hogy mely címek a lakcímek és melyek a postacímek (de az sincs kizárva, hogy valóban ugyanaz a cím példány szerepeljen egyszerre mindkét kapcsolatban). Lakcím esetén láthatjuk, hogy legalább egy cím meg van követelve, tehát Vásárló létrehozásakor azonnal létre kell jönnie az első lakcímnek is, vagy a Vásárló osztálynak meg kell követelni azt.

Page 13: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Kompozíciót egy kitöltött rombusz jelöli. Itt is a gyermek mutat a szülő felé, vagy mondhatjuk úgy, hogy a rész az egész felé. Ez a diagram a fentebb leírt helyzetet ábrázolja. Egy számlához tartoznia kell legalább egy fizetési módnak, de lehet akármennyi is. Viszont, ha egyszer létrejött egy ilyen struktúra, akkor nem megbontható. Csak egészben semmisíthető meg, tehát például a számla törlésekor törlődnek a hozzá tartozó fizetési módok is.

Szekvencia

Eddig főleg az objektum modellünk struktúrájáról volt szó. Ez lényegében az adatmodellt jelenti. Meg kell vizsgálnunk viszont a folyamatait, műveleteit, viselkedését is.

Az világos, hogy objektumoknak vannak metódusaik. A metódusoknak egy része csak közvetlenül az adott objektummal dolgozik, viszont más esetekben különböző osztályok, objektumok egymás metódusait hívogatják, sokszor igen hosszú és bonyolult láncolatokban. Egy ilyen lánc egy szekvencia.

Gondoljunk először egy ilyen szekvenciára úgy, hogy objektumok, metódusok nélkül képzeljük el. Tehát csak van előttük egy egybefüggő, hosszú műveletsor. A mi feladatunk az, hogy ennek a folyamatnak az egyes részeit „kiosszuk” az objektumaink között a helyes módon. Fel kell darabolnunk, és ezeket a darabokat szétosztani az objektumok között úgy, hogy minden objektumra pontosan annyit jusson belőle, amennyi szükséges és elégséges, nem több, nem kevesebb.

Egyszerűbben szólva, meg kell tudnunk állapítani, hogy a folyamat egyes részei mely objektumok „felelősségei” lesznek, és hogy mennyi és milyen metódusokra bomlanak. Ezt hívjuk dekompozíciónak.

Tehát egy hosszabb folyamatot kisebb darabok láncolatába tördelek. A kérdés itt az, hogy pontosan hogyan tördeljem? A töredékek mely objektumok felelősségei (metódusai) lesznek? Ezen kérdések eldöntése rendkívül fontos, hogy az objektum modellünk kellőképpen rugalmas, jól módosítható és jól bővíthető legyen.

Itt több programozási elv is segítségünkre lesz, amikkel sokan más egész biztosan találkozhattak:

• Újrafelhasználhatóság / hordozhatóság • Procedurális absztrakció • Információ elrejtés

Page 14: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Az újrafelhasználhatóság és hordozhatóság elve:

Vegyünk egy programkód részletet. Mindegy, hogy ez egy metódus, egy függvény, vagy akár egy teljes objektum. Egy kód akkor hordozható, teljes mértékben, ha független minden külső tényezőtől. Ez jelent gyakorlatilag mindent, ami nem kívül esik a kód lokális terén. Egy függvény esetén ez azt jelenti, hogy csak a lokális változóival, és a kapott paraméterekkel dolgozik, semmilyen más globális eredetű dologra (függvényre, változóra, osztályra) nem hivatkozik, sőt, mellékhatása sincs!

Ezek a feltételek azt biztosítják, hogy a függvény akármilyen környezetbe átvihető lesz (adott nyelvi környezeten belül), és mindig meglesz minden, a működéséhez szükséges tényező, és ugyanarra a bemenetre mindig ugyanazt a kimenetet produkálja.

Ugyanez az elv metódusok esetén annyival módosul, hogy a metódusnak elnézzük, ha a saját objektuma attribútumaival dolgozik (hiszen ez a legtöbb példánymetódus célja).Osztályok, objektumok esetén a hordozhatóság azon múlik, hogy az objektum hivatkozik-e bármilyen más, globális eszközre (osztályokat is beleértve), kivéve azokat, amiket paraméterként kapott, metódusain, konstruktorán keresztül.

A hordozhatóság azt biztosítja, hogy egy folyamat független a globális környezettől, így minden esetben megbízhatóan pontosan azt csinálja, amit elvárunk tőle, függetlenül attól hogy honnan, vagy hogyan kezdeményeztük ezt a folyamatot.

Ezekre az elvekre általánosságban érdemes törekedni. Mielőtt viszont valaki nyakig beleásná magát abba, hogy kódjait teljes mértékben függetlenítse a globális környezettől, el kell mondjam, hogy ez korántsem egyszerű feladat. Sok rendszer kiegyezik egy kompromisszumban a hordozhatóságot illetően, és megengedi magának, hogy az objektumai globális eszközöket érjenek el, olyanokat, amik mindig léteznek, és amiknek nem, vagy csak kis mértékben változik az állapota.

Procedurális absztrakció:

Ez talán az egyik legfontosabb eszköz, eljárásmodell szervezésében. Vérbeli eljárás-orientált elv. Ha van két kódrészletem, két függvény, metódus, vagy akármilyen egyszerű vagy összetett művelet, amik nagyon hasonlóak, hasonló tevékenységet végeznek kis különbségekkel, akkor felmerülhet az emberben, hogy miért ne lehetne a kettő csak egyetlen művelet? Egyetlen kód, ami csak egy helyen van megírva, de el tudja látni mindkét feladatot, valamilyen paraméterezés, vagy egyéb külső tényező hatására.

Vegyünk példának egy algoritmust, ami egy egyváltozós függvényt rajzol ki egy grafikonra. Legyen ez a függvény a sin(x). Az algoritmus kirajzolja a függvény grafikonját x=0 -tól, x=1 -ig.

Tegyük fel, hogy később szeretnénk egy másik függvényt is megjeleníteni, legyen ez az f(x)=2x függvény, x=0 -tól x=500-ig. Rendkívül hasonló a kettő, és tegyük fel, hogy ugyanolyan grafikont állítanak elő. Pazarlás lenne még egyszer írni egy függvényrajzolót, hiszen a kódnak egy nagy része mindkettőben ugyanolyan lenne.

Megoldhatom ezt a problémát úgy is, hogy írok egy eljárást, vagy metódust, vagy teljes objektumot, ami immár paraméterként kapja a kirajzolandó függvényt, és szintén paraméterként kapja az intervallumot is. Tehát megteremtettem egy absztrakt függvényrajzolót, ami innentől kezdve csak egy helyen van megírva, és sokkal többféle függvényt is meg tud jeleníteni, nem csak kettőt.

Page 15: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

A legtöbben erre azt mondanák, hogy evidens, nyilván ezt minden programozó átlátja. Csakhogy nem minden helyzet ennyire evidens, illetve nem csak arra érdemes felkészülni ami a legelső specifikációban szerepel. Törekedni kell az általánosításra. Például ebben a függvényes példában valószínűleg sokaknak nem jutott eszébe, hogy érdemes lehet azt is általánosítani, hogy a kirajzolt grafikon milyen kimenetre menjen. Képernyőre? Fájlba? Más megjelenítő eszközre? Vagy ne is jelenítsen meg semmit csak térjen vissza a kimenettel?

Bármi előfordulhat, érdemes minél jobban általánosítani, és mindenre felkészülni…. és még mielőtt valaki azt mondaná, hogy ha nincs benne valami a specifikációban, miért készüljön fel rá, megemlíteném, hogy a valós életben szoftvermódosítások és bővítések sokszorosan meghaladják a nulláról fejlesztett szoftverek számát, és munkaidejét!

Tehát a kódjaink legyenek minél általánosabbak, rugalmasabbak, mert lehet, hogy már holnap szükség lesz rá!

Információ elrejtés elve:

Ez az elv megjelent már az eljárás orientált világban is, de legfőképp az OO világban bontakozott ki. Ez az egyik legfontosabb OO irányelv, az objektumok viselkedésének a kialakításában.

Az objektumok, akárcsak az emberek, független, privát élettel rendelkező egyéniségek. Ugyanúgy, ahogy az emberek között, úgy az objektumok között sem szép dolog másnak a dolgába ütni az orrunkat.

A lényeg röviden szólva annyi, hogy minden objektum a saját tevékenységét zárja magába, és rejtse is el a külvilág elől. Ehhez viszont az is hozzátartozik, hogy ne is követeljen semmi olyat a külvilágtól a különböző tevékenységeihez, ami nem az ő dolguk.

Például vegyünk egy könyvtárost, aki hatalmas mennyiségű dokumentumot kezel, felügyel. Tegyük fel, hogy én szeretnék kikérni egy könyvet, aminek csak a címét tudom. Nyilván a könyvtáros ki kell, hogy keresse valami jegyzékből, hogy ki a szerző, és ez alapján a könyv melyik polcon, melyik sorban található. Akárhogy is teszi, egy a lényeg: nekem semmit, de semmit nem kell tudnom arról, hogy ő hogy rendszerezi a könyveket, és hogyan keresi elő. Megmondom mit kérek, várok valamennyit, és megkapom. Ennyi. Ez ez ideális helyzet.

Teljesen mindegy számomra, hogy mikét vannak a könyvtár polcai rendezve. Még csak nem is kell tudnom róla. Arról sem kell tudnom, hogy a könyvtáros hogyan keresi elő a címe alapján a könyvet. Viszont az is fontos, hogy nekem semmilyen olyan extra információt nem kell átadnom a könyv címén kívül, aminek köze lenne a könyv nyilvántartási rendszerhez.

Gondoljuk csak el, mi lenne ha azt is tudnom kellene, hogy a könyv melyik sorban van. Egyrészt, ez az információ teljesen fölöslegesen van a birtokomban, hiszen úgysem én keresem elő a könyvet. Másrészt, gondoljuk el, hogy mi lenne ha egy szép napon ki akarjuk kérni a könyvet, megadjuk a címét, és a polcot, csakhogy kiderül, hogy a legutóbbi alkalom óta a könyvtárat átrendezték! A könyvtáros sajnálkozva közölné, hogy ilyen számú polc nincs, és nem tud segíteni. Joggal lennénk felháborodva, hiszen ki másnak lenne a felelőssége tudni, hogy egy könyv melyik polcon van, ha nem könyvtárosé?

Page 16: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Átültetve ezt a programozási világba, ha a könyvtáros egy objektum lenne, és rendelkezne egy getKönyv() nevű metódussal, akkor a jó megoldás az lenne, hogy csak egy könyvcím paramétert kér ahhoz, hogy visszaadja a kért könyvet, a hívó félnek pedig abszolút semmilyen módon nem kell részt vállalnia a metódusban zajló folyamatokban, és nem is kell tudnia róla semmit! Tehát az az objektumok felelősségei nem keverednek.

Ennek az a csodálatos következménye van, hogy ha a getKönyv() metódus mögött a könyvtár struktúrája egyik napról a másikra megváltozik, a hívó félnek ebből semmi sem tűnik majd fel, az élet zavartalanul megy tovább. Ezt a jelenséget úgy hívjuk, hogy interfész-implementáció függetlenség. Vagyis a getKönyv() metódus alakja ugyanolyan marad, de mögötte az implementáció akár teljesen másmilyen is lehet, mégis minden működik.

Tehát a legfontosabb feladat egy folyamat lebontásánál, hogy jól osszuk ki a felelősségeket az objektumok között. Minden, a folyamatban részt vevő objektum pontosan annyi feladatot kapjon amennyi neki jár, és ebből ne terheljen rá semmit a hívó felekre.

Szintén tipikus szabály, hogy minden objektum csak saját magát manipulálhatja közvetlenül, mindenki mástól csak „kérheti” azt.

Például, ha szeretnék egy barátomtól kérni ezer forintot, akkor mi a helyes lépés? Odamegyek, kiveszem a pénztárcáját a zsebéből, kinyitom, kiveszem az ezrest, becsukom, aztán visszarakom a tárcáját a zsebébe, és megyek a dolgomra? Nem, mivel az OO világ illedelmes világ, és a barátom pénztárcája az ő tulajdona, nem az enyém, tehát nem szabad piszkálnom. Helyette megkérdezem, hogy kaphatok-e ezer forintot. Az is lehet, hogy azt mondja, hogy nem. De tegyük, fel hogy rendes, és van is pénze, szépen előveszi a tárcáját, stb., és megkapom az ezrest. Nem tolakodtam be a privát szférájába, sőt, betartottuk az információ elrejtés elvének a másik oldalát is, hiszen nekem nem kell tudnom, hogy hogyan kell elővenni a pénztárcát, kinyitni, stb. Az is lehet, hogy a barátomnál nincs elég készpénz, ezért elmegy előbb a bankba és vesz ki pénzt, vagy lehet csak tízezrese van, és előbb felváltatja. Mindegy mit teszt, nekem nem is kell tudni, lényeg, hogy ugyanúgy kellett kérnem, és ugyanúgy is kaptam meg a kezembe.

Szóval helyesen így nézne ki leprogramozva:

barát.pénztKér(1000);

és helytelenül:

barát.pénztárca.pénzKivesz(1000);

Page 17: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Most lássunk a folyamatok ábrázolását UML-ben:

Az első és legfontosabb dolog, hogy a szekvencia diagram nem folyamatábra. Vagyis nem írja le részletesen, hogy egy metódus mit csinál, nem jeleníti meg a feltételes elágazásokat, ciklusokat, egyszóval a vezérlési szerkezeteket.

Ez a diagram csak arra szolgál, hogy a rendszerünknek a „csontvázát” leírjuk. Ez azt jelenti, hogy nagyrészt csak azt mutatjuk be vele, hogy egy folyamat milyen objektumok mely metódusain folyik keresztül.

Az ábra egy objektum egy metódusának a meghívását mutatja. A diagramon függőleges irányban (fentről lefele) az időt látjuk, vízszintesen pedig a hívási láncot.

Az objektum osztályneve egy dobozba van írva, a doboz aljából pedig szaggatott vonalként halad lefele az úgynevezett életvonal. Ez a vonal mutatja azt, hogy meddig létezik az objektum. Az életvonalon a metódushívás kezdetétől indul és halad lefele az aktivációs vonal. Ez az adott metódus életének az

idejét mutatja. A metódus neve egy nyílra van írva ami az aktivációs vonal tetejére mutat.

Page 18: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Itt látunk példát egy konkrét folyamatra:

A folyamat kezdődik a pénztKér() metódus meghívásával. Ez meghívja a pénztárcának a pénzKivesz() metódusát. Láthatjuk, hogy ennek az aktivációs vonala lentebb kezdődik, hiszen időben később történik mint a pénztKér() metódus meghívása. Továbbá fentebb is ér véget a vonal, mint a pénztKér() aktivációs vonala, hiszen hamarabb is fejeződik be a metódus. A visszatérést egy szaggatott vonalas nyíl jelöli.

A pénzKivesz() metódus aktivációs vonalán láthatunk egy érdekes esetet. Meghívja a címletEllenőriz() metódust, ami szintén ugyanannak az objektumnak a metódusa, ezért ennek az aktivációs vonala az őt meghívó metódus aktivációs vonalának az oldalán helyezkedik el, a hívási és visszatérési nyilak pedig visszagörbülnek.

A szekvencia diagram ugyan nem folyamatábra, viszont sokszor a metódus belső működésében lényeges információkat (például fontos feltételes elágazásokat) megjegyzésekként odaírják a kritikus pontokhoz, ahogy az az ábrán is látható.

Természetesen ez a fajta diagram is sokkal gazdagabb az itt bemutatott példák jelöléseinél, de mi most csak az alapokkal foglalkozunk.

Page 19: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Állapot

Az objektumainknak nem csak műveletei, kapcsolatai és attribútumai vannak, hanem állapotaik is. Hagyományos OO terminológia szerint egy objektum állapotait az attribútumainak az értékei adják. Vagyis egy Vektor osztály esetén ami x, y, z attribútumokkal rendelkezik, az objektum aktuális állapota ezen három attribútumnak az értéke. Nekünk az állapot most nem ezt fogja jelenteni, ez egy sokkal absztraktabb szintű fogalom lesz.

Ami azt illeti, az előbb említett Vektor osztálynak nincsenek is állapotai. A mi fogalmaink szerint az állapot ennél sokkal erősebb fogalom. Állapotnak azt tekintjük, amitől függ valamilyen módon az objektum viselkedése, vagy akár egy objektum struktúra viselkedése is. A példaként felhozott Vektor nem ilyen, mindig pontosan ugyanúgy viselkedik, teljesen mindegy milyen x, y, z értéke.

Fontos azt is észben tartani, hogy objektum állapotai nem feltétlen attribútumokként jelennek meg (bár implementációban többnyire így jelennek meg), ezért továbbra sem szabad implementációs szinten elképzelni ezeket az állapotokat. Még mindig absztrakt, koncepcionális szinten vagyunk.

Tehát akkor mi is egy „valódi” állapot? Egy jó példa a fentebb már említésre került termék és akciós termék. Egyetlen objektum, aminek van két állapota, tehát akciós-e vagy sem. Van persze ára is, neve is, meg sok más adata, de azok számunkra nem részei az állapotnak, azok „csak adatok”.

Termék és akciós termék viszont valóban viselkedésbeli különbséget jelent. Például, ha a terméknek van egy getÁr() metódusa, akkor attól függően, hogy akciós-e vagy sem, másféle eredményt ad vissza. Ez már egy igazi állapot. Sőt, az is lehet, hogy csak bizonyos vásárlók vásárolhatnak akciósan, például akik klubtagok. Így már látható, hogy a termék ezen állapotának sokkal messzemenőbb következményei vannak, mint csak, hogy mennyibe kerül.

Egy akciós/nem akciós állapot nyilván egy attribútummal lesz reprezentálva implementációs szinten. Viszont, ahogy említettük, nem szabad rögtön így elképzelni egy állapotot. Lehet olyan is, hogy egy állapotot nem egy attribútum reprezentál, hanem például egy kapcsolat (persze a kapcsolat is megjelenthet egy attribútumként, de sokszor ez sem igaz).

Vegyünk egy Lomtár objektumot, aminek két állapota üres / nem üres. A lomtárba objektumok kerülnek, ami jelentse most azt, hogy a lomtár egy asszociációt fog kialakítani az objektumra. Ebben az esetben azt, hogy a lomtár üres, vagy sem, nem egy attribútum határozza meg, hanem az, hogy a kapcsolatban hány objektum szerepel. Sőt, maga a lomtárba rakott tétel is rendelkezhet ez alapján kétféle állapottal: szemét / nem szemét.

Láthatjuk tehát, hogy ez az állapot fogalom sokkal absztraktabb és magasabb szintű, mint pusztán az attribútumok értékének az összessége.

De hogyan is segít ez nekünk egy rendszer megtervezésében, programozásában? Nos, mivel az állapotokhoz különböző viselkedések kötődnek, nekünk ezeket kell felderítenünk és megvalósítani, továbbá azt, hogy melyik állapotból milyen más állapotokba juthatunk el, és ezt milyen műveletekkel tehetjük meg. Tehát össze kell szedni, hogy milyen állapotok vannak, és ezekben az állapotokban miket szabad, és miket nem szabad csinálni, és azt is, hogy egyik állapotot egy másikba milyen műveletek – vagy más néven átmenetek – viszik át.

Az átmenetek is tisztességes műveletek, vagy valamilyen más műveletnek a részei, vagy következményei (pl. lomtár kiürítése).

Page 20: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Egy állapot diagram a következőképpen néz ki, például a fentebb említett Termék objektumra:

Az állapotok lekerekített téglalap mezőkbe vannak írva, és az átmenetek az állapotok között nyilakkal vannak jelezve, amikre az átmenet nevét írjuk. Ez nem egy metódus vagy egyéb programozási eszköz neve, hanem egyszerűen csak egy név amivel megnevezzük azt a műveletet vagy eseményt, ami átviszi az objektumot egy állapotból a másikba.

Egy fontos és kötelező része az állapot diagramnak a kezdőállapot jelölése, vagyis hogy az objektum létrejöttekor melyik állapotba kerül alapértelmezetten.

Az állapot diagram az UML-nek a legkevésbé egzakt formalizmusa, igazán csak az az egyértelmű, hogy vannak állapotok, és átmenetek. Az, hogy maga az átmenet micsoda, és milyen féltételekkel történhet meg, már képlékeny dolog, és a tervezőre van bízva hogy, hogyan jeleníti meg a diagramon.

Léteznek úgynevezett összetett állapotok is. Ez azt jelenti, hogy egy adott állapoton belül lehetnek al-állapotok is. Ekkor az al-állapotok állapot diagramját a szülőállapot dobozába rajzoljuk.

Természetesen ez az állapot diagramnak is csak egy felületes bemutatása, kezdő rendszerfejlesztőnek a koncepció és a módszer megértése a legfontosabb. Tehát felderíteni az állapotokat, az azokat aktiváló eseményeket, és a hozzájuk kapcsolódó viselkedést.

Page 21: Rendszerfejlesztés - itcluster.hu · A dolgozó-ügyfél példánál maradva, a 3-as pont tűnik a legmegfelelőbbnek, hiszen a dolgozónak és az ügyfélnek van közös része,

Utószó

Ennek a tanulmánynak a célja azon elvek és módszerek bemutatása amikkel az ember továbbléphet

egyszerű programozási szintről egy magasabb szintű, átgondoltabb szoftverfejlesztési szintre.

Ezeknek a megértése sokkal fontosabb mint maga a formalizmus.

Az életben a tapasztalat azt mutatja, hogy magasabb szintű rendszerfejlesztési tudás nélkül igen

gyenge minőségű munkák szoktak születni, amik természetesen súlyos pénzeket és időt is

követelnek, ezért nem tudom eléggé hangsúlyozni, hogy mennyire fontos az embernek képeznie

magát ebbe az irányba, ha saját maga szeretne komolyabb rendszereket megtervezni. Ehhez

önmagában egy programozási nyelv, és eszközeinek ismerete nem elégséges.

Remélem az itt leírtak hasznos információként szolgáltak az érdeklődőknek, és inkább

ösztönzésként mint elrettentésként.