4. Egy lakás biztonsági rendszere
120
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.1 A feladat
Az elızı két esettanulmány „mőszaki” eszközök számítógépes szimulációjával foglalkozott, az itt következı alkalmazás már nem szimuláció, hanem egy fizikailag is létezı berendezés (hardver) vezérlı szoftvere. – Az egyszerőség kedvéért egy konkrét lakás rendszerét tervezzük meg, de helyenként utalunk a bıvítés / kiterjesztés lehetıségeire is. Az épületekben alkalmazott biztonsági rendszerek vezérlése kapcsolótáblá(k)ról és a védett helyiségekben elhelyezett érzékelıkrıl vett jeleket dolgoz fel. Az utóbbiak miatt ennek a rendszernek (a korábbi esettanulmányoktól eltérıen) a felhasználói eseményeken és az idıeseményen felül más eseményekre is reagálni kell. A konkrét lakásnak két bejárata van, mindkét bejáratnál (belül a lakásban) szükség van egy-egy kapcsolótáblára (lásd a 4.1. ábrán). Mivel a lakók a két bejáratot alternatívan használják, fontos, hogya a vezérlırendszer élesítése, hatástalanítása vagy mőködésének beállítása bármely kapcsolótábláról elvégezhetı. (A két bejárat és ezzel a két kapcsolótábla csak az adott esetre jellemzı, egyébként a rendszer további kapcsolótáblákkal bıvíthetı.) A lakás hat zónára (helyiségre) tagolódik. A zóna fogalma lehetıvé teszi, hogy a lakásban a riasztást csak részlegesen (csak bizonyos zónákra kiterjedıen) élesítsük. Például a lakás 1-es és 4-es zónájában egy vendég tartozkódik, amikor a lakó távozni akar otthonról, akkor a riasztót úgy élesítheti, hogy az élesítésbıl az említett zónákat kiiktatja. (Természetesen egy nagyobb lakásban a rendszer több zónából is állhat.) Az adott lakás a következı érzékelık elhelyezését teszi szükségessé (M: mozgásérzékelı, N: nyílászáróérzékelı): • 1. zóna: 1M, 2N; • 2. zóna: 1M, 3N; • 3. zóna: 2M, 4N; • 4. zóna: 1M, 1N; • 5. zóna: 1M, 2N; • 6. zóna: 1M, 2N. Természetesen egy nagyobb épület nagyobb helyisége (zónája) több érzékelı felszerelését kívánhatja meg.. 4.1. ábra: A biztonsági rendszer kapcsolótáblája
A fenti felsorolásban az érzékelık két típusát (mozgásérzékelı és nyílászáróérzékelı) azért is meg kellett különböztetni, mert a riasztás élesítése történhet • mindkét típusú érzékelıre vonatkozóan (amikor távozunk a lakásból); • csak a nyílászáróérzékelıkre vonatkozóan (amikor a lakásban tartózkodunk). Az érzékelık meglehetısen buta komponensek, ha üzemképesek, mindössze két dolgot tudnak: • Jelzik, ha (a típusuknak megfelelı) változást érzékeltek függetlenül attól, hogy a zónájuk élesítve van-e vagy sincs.
EGY LAKÁS BIZTONSÁGI RENDSZERE •
121
Nyugtázzák az üzemképes állapotukat. Erre azért van szükség, mert a rendszernek nem csak az jelent vészeseményt, ha egy élesített zóna riasztója riaszt, hanem az is, ha az érzékelı azért nem riaszt, mert levágták a rendszerrıl.
Hogy egy kicsit bonyolultabb legyen a feladat, megengedjük, hogy az üzemképesség nyugtázása szempontjából kétféle érzékelı legyen a rendszerben, méghozzá függetlenül attól, hogy mozgásérzékelırıl vagy nyílászáróérzékelırıl van-e szó: Az egyik fajta csak akkor nyugtáz, ha a rendszer lekérdezi, a másik rendszeres idıközönként (pl. másodpercenként nyugtázó jelet küld a rendszernek. – Az elıbbiekben minden zónára megadtuk, hogy abban mennyi mozgásérzékelı, illetve mennyi nyílászáróérzékelıre van szükség, mert az egyértelmően következik a lakás tulajdonságaiból (ajtók száma, ablakok száma); ezzel szemben azt nem írjuk le, hogy melyik érzékelı milyen módon nyugtázza az üzemképességét, mert az attól függ, hogy a késıbbiekben milyen érzékelıket lehet majd beszerezni. A rendszer felhasználói felületét képezı kapcsolótáblára a 4.1 ábrán mutatott változat csak az egyik lehetıség. Ráadásul ez a változat a fentebb elmondottaknak ellentmondani látszik, mivel nincs rajta sem élesítés, sem kiiktatás kapcsológomb. E tények azonban semmilyen gondot nem jelentenek, hiszen a 12 gomb lehetséges kombinációival többféle parancsot lehet kódolni, mint amennyire a rendszernek valaha is szüksége lehet. Íme néhány példa: *0
Élesítés távozással
*1
Élesítés otthon tartózkodással
*2#n#
Az n. zóna kiiktatása a következı élesítés alól. Például *2#4# paranccsal a 4. zónát lehet kiiktatni. – Egymás után több zóna kiiktatása is megadható, azaz több zóna is kivonható a következı élesítés hatása alól. Hatástalanítás egy négyjegyő jelszókóddal. – Ez értelemszerően csak élesített állapotban alkalmazható. A jelszó eltévesztése esetén a # gomb lenyomása után a jelszó megadása elılrıl kezdhetı.
nnnn
… A rendszer mőködésére adott konkrét példákban a felhasználói parancsok a fenti gombkombinációkkal jelennek meg, ugyanakkor a tervezésben, a modellekben már nem tükrözıdnek. – Az elızı két esettanulmány éppen eleget foglalkozott gombesemények kezelésével ahhoz, hogy a jelen esettanulmányban a probléma ezen részét elhanyagolhassuk. Sıt, az még elıny is, ha a rendszert úgy tervezzük, hogy az közömbös legyen az iránt, hogy a kapcsolótábla milyen típusú, milyen gombokat, illetve kijelzési lehetıségeket tartalmaz. A rendszer csak azt feltételezi a kapcsolótábláról, hogy arról valamilyen módon a következı üzenetek érkezhetnek a rendszer központi vezérléséhez: • Élesítés távozással. • Élesítés otthon tartózkodással • Adott zóna kiiktatása a következı élesítés alól. • Hatástalanítás. Megjegyzés: További felhasználói parancsok is elképzelhetık, de az esettanulmány csak az itt felsoroltakkal foglalkozik. Az ellenkezı irányban azzal a feltétételezéssel élünk, hogy a kapcsolótábla valamilyen módon közölni képes bizonyos információkat a felhasználóval, mint például a következık: • A rendszer üzemkész – minden érzékelı üzemképes. Ezt pl. a 4.1. ábra szerinti kapcsolótáblán az Üzemkész led világítása jelezheti.
122
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK • • • •
•
Az egyébként üzemkész rendszer mőködésének folytatását valamilyen veszély fenyegeti (pl. az akkumulátor töltési szintje lecsökkent). Ezt pl. a Rendszer led sárga villogása (és esetleg egy elviselhetı gyakoriságú, pittyegı hang) jelezheti. A rendszer élesítve van (az Élesítve led pirosan világít). Adott zónában valamilyen mozgás észlelhetı, vagy valamely nyílászáró nyitva van (függetlenül attól, hogy a rendszer élesítve van-e). Ez pl. azzal jelezhetı, hogy a zónához tartozó led pirosan világít. Adott zónában valamely érzékelı üzemképtelenné vált. Jelzése: a Rendszer led sárgán, a zónához tartozó led pedig pirosan villog. – De ha a zóna élesítve van, akkor természetesen bekapcsol a riasztás is (megszólal a sziréna, értesítés megy a biztonsági szolgáltató céghez). Eddig csak a ledek útján történı jelzéseket említettünk, pedig ott van még egy, a digitális óráéhoz hasonló szöveges kijelzı is, amely a felhasználónak szóló további üzenetekre ad lehetıséget.
A több kapcsolótábla jelenléte ellenére ez a rendszer szó szerinti értelemben nem többfelhasználós rendszer. Gyakran csak azért szerelnek fel több kapcsolótáblát, mert ugyanaz a lakó (felhasználó) alternatívan hol egyik, hol másik ajtón közlekedik. – Ettıl lényegesen különbözik az a helyzet, amikor a lakás különbözı zónáit különbözı lakók egymástól függetlenül veszik igénybe (egymástól függetlenül tartózkodnak otthon, illetve egymástól függetlenül távoznak el), és mindenki a saját mozgásának megfelelıen ad ki parancsokat a hozzá közel álló kapcsolótábláról. Azonban a lakásokban alkalmazott biztonsági rendszerek a teljesen független párhuzamos használatot általában nem támogatják, mert egy olyan igényt egyszerőbb több, teljesen elkülönült redszerrel megoldani. Ha a lakásban egy rendszer van egyetlen központi „aggyal”, akkor csak korlátozottan független használatra van lehetıség, mert a különbözı helyiségekben lakóknak figyelemmel kell lenni egymásra, egyeztetni kell egymással. Például amikor az A lakó távozik, meg kell gyızıdnie, hogy a másik rész B lakója otthon van-e. Ha B otthon van, akkor az A-nak úgy kell élesítenie a rendszert, hogy abból elıbb a B zónáit kiiktatja. Amikor A hazaérkezik és hatástalanítja a rendszert, akkor tisztában kell lennie azzal, hogy a hatástalanítás minden zónára kiterjed (nem csak azokra, amelyeket ı élesített) Tehát ha A után B is távozott, aki már az összes zónát élesítette, akkor az A által kiadott hatástalanítás parancsra B zónái is hatástalanítódnak. Ezért A-nak ekkor is meg kell gyızıdnie arról, hogy B otthon van-e már, és amennyiben nincs, akkor a B zónáinak élesített állapotát vissza kell állítania. Ez az alkalmazás annyiban mégis hasonlít a többfelhasználós rendszerekhez, hogy konkurens eseményeket kezel. Errıl a 4.4.3. szakaszban egy kicsivel több szó esik majd.
EGY LAKÁS BIZTONSÁGI RENDSZERE
123
4.2 A probléma használati eset modellje 4.2.1 A használati eset diagram kétféle élesítés paranccsal A lakás biztonsági rendszerének használati eseteit a lakó által a kapcsolótáblákon kezdeményezhetı mőveletek (parancsok) képezik, amelyeket a 4.1. alfejezetben így rögzítettünk: • Élesítés távozással. • Élesítés otthon tartózkodással • Adott zóna kiiktatása a következı élesítés alól. • Hatástalanítás. A 4.2. ábra mutatja az egyik lehetséges megoldást..
4.2. ábra: A probléma egy lehetséges használati eset diagramja – Kétféle élesítés parancs esete
Mint azt az elızı esettanulmányoknál már láttuk, a használati eset modell nem csak a diagram(ok)ból áll. A használati esetekhez (a „krumplikhoz”) részletes (verbális vagy formalizált) leírás főzhetı. – Példánk esetében a kapcsolótáblák használati utasításaihoz hasonló leírásokra kell gondolni. Ellenırzı/magyarázó kérdések (a kérdések a 4.2. ábrára vonatkoznak): 1. A Zóna kiiktatása miért «extend», Mert az élesítésnek nem mindig része (azt miért nem «include» sztereotípusú függés- nem mindig elızi meg) valamely zóna kiiktatása. Tehát itt nem kötelezı részrıl, sel kapcsolódik az Élesítés használati hanem opcionális kiegészítésrıl van szó. esethez?
124
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
2. Mi indokolja, hogy az Élesítés távozással és az Élesítés otthon tartózkodással használati esetek általánosításaként bevezessük az Élesítés használati esetet? 3. A lakó mellett miért nem jelenik meg a betörı is a rendszer aktoraként? (Ilyen kérdést a szerzı egyedül képtelen lett volna kitalálni. A probléma szemináriumi feldolgozásakor az egyik hallgató javasolta a betörıt is felvenni az aktorok közé.)
Mert a két eset feldolgozásának van közös része (a nyílászárók érzékelık élésítése), az is közös jellemzıjük, hogy mindkettınek opcionális kiegészítése a Zóna kiiktatása használati eset. Ha egy gyakorlott fejlesztıt egy ilyen rendszer tervezésével bíznak meg, az a betörıben csak eseményforrást, kezelendı tényezıt lát. Az ı felfogása szerint a betörı ugyanúgy nem felhasználója a biztonsági rendszernek, ahogy például az idıjárás sem felhasználója a meteorológiai elırejelzı rendszernek, vagy a pecsenyekacsa a grillsütınek. Az Olvasó azonban joggal veti közbe, hogy a pecsenyekacsa soha nem kezeli a grillsütıt, a betörı viszont úgy is bejuthat a lakásba, hogy megszerzi a kódot, amellyel hatástalanítja a rendszert, tehát végeredményben használja a rendszert. Akkor miért is nem felhasználó? – Talán a következı kérdés a kezdıket is elgondolkodtatja: Milyen elérési / felhasználói jogokat rendelne a betörı szerepkörhöz? A rendszerterv részeként a tervezı értelemszerúen nem konkrét felhasználókat, hanem felhasználói szerepköröket (aktorokat) tervez. Ezeket azért tervezi, mert a szerepkörök azok a kategórák, amelyekhez köthetıen megadható az adatokhoz és a programfunkciókhoz való hozzáférés joga. – Betörı szerepkör tervezését csak az a képtelen ötlet indokolná, ha a betörıknek is hozzáférési jogokat szeretnénk osztani. Amikor a betörı a megszerzett hatástalanító kódot a kapcsolótáblán bebillenytőzve használja a rendszert, akkor azt a lakó szerepében teszi fel. Ez ugyanaz az eset, mint amikor valaki megszerzi egy felhasználó usernevét és jelszavát, és azzal (egy másik személy identitásával és jogaival) lép be egy alkalmazásba. – Összefoglalva: Mint ahogy általában (más alkalmazásoknál) nincs szükség jogosulatlan felhasználó szerepkörre, ugyanúgy nincs szükség a mi rendszerünk esetében sem a betörı szerepkörre.
EGY LAKÁS BIZTONSÁGI RENDSZERE
125
4.2.2 A használati eset diagram élesítési mód paranccsal Az elızı szakaszban adott használati eset diagram az ugyanott adott parancskészletnek felel meg. Mi van akkor, ha a felhasználónak ez a parancskészlet nem felel meg, vagy a forgalomban éppen más parancskészletet tudó kapcsolótábla kapható? Tegyük fel, a lakó kényelmetlennek találja mindig odafigyelni, hogy a kétféle élesítés parancs közül éppen melyiket alkalmazza. Jobb lenne neki egyetlen élesítés parancs (esetleg egy élesítés gomb) és egy külön, élesítési módot kapcsoló parancs (vagy gomb). Az utóbbi paranccsal a lakó olyan módba állítja az élesítést, amelyet a leggyakrabban használ, ezt követıen elegendı csak a sima élesítés parancsot használnia. Így az élesítési mód parancsot a lakónak csak abban a ritka esetben kellene alkalmaznia, amikor az egyébként szokásostól eltérı módon akarja élesíteni a rendszert. – A 4.3. ábra a használati eset diagramja már ezt a parancskészletet tükrözi.
4.3. ábra: A probléma másik lehetséges használati eset diagramja – Élesítési mód parancs esete
126
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.3 A probléma statikus modellje 4.3.1 A konkrét rendszer objektumdiagramja A 4.1. alfejezetben leírt konkrét rendszer talán már elég sok elembıl áll ahhoz, hogy ne számítson túlzásnak egy objektumdiagrammal (lásd a 4.4. ábrát) elıkészíteni a késıbbi osztálydiagramot.
4.4. ábra: A konkrét lakás biztonsági rendszerének objektumdiagramja
EGY LAKÁS BIZTONSÁGI RENDSZERE
127
Ellenırzı/magyarázó kérdések (a kérdések a 4.4. ábrára vonatkoznak): 1. Miért nem láthatók számosságok a kapMert ezek a vonalak kapcsolatok, nem pedig csolatokon (kapcsolóvonalakon)? asszociációk. (A kapcsolat konkrét objektumok közötti viszony. Az asszociáció az azonos értelmő kapcsolatok típusszintő reprezentációja, és mint ilyen osztályok közötti viszony.) Egy konkrét kapcsolat mindig egy objektumot kapcsol össze egy objektummal, ezért nincs értelme a kapcsolat számosságáról beszélni. A számosságok az osztálydiagramon szereplı asszociációkra értelmezett jellemzık. 2. A kapcsolatok semelyik végükön nem Mert mindegyik kapcsolat mentén a navigávégzıdnek nyílban. Miért nem? ció kétirányú. Például az érzékelınek látni kell a zónát, mert annak jelez, ha változást észlel; a zónának is látni kell az érzékelıt, mert szabályos idıközönként ellenıriznie kell annak üzemképességét. (Más asszociációk esetében az olvasóra vár a hasonló viszony belátása.) 3. A diagramon több azonos hivatkozású A (b) értelmezés a helyes. Az említett példáobjektum látható, Például mÉrzékelı[1] ban több különbözı érzékelırıl van szó: Az egyik az, amelyre a zóna[1] hivatkozik hivatkozású objektumból összesen hat is van sorban a zóna[1] … zóna[6] mÉrzékelı[1] névvel, a másik az, amelyobjektumokra akasztva. Vajon itt re a zóna[2] hivatkozik mÉrzékelı[1] (a) az azonos hivatkozás azonos objektunévvel, és így tovább. mot jelent, amely többszörösen jelenik Ez felfogható úgy is, hogy az mÉrzékelı[1] meg a diagramon; vagy név egy változót jelöl, és a zóna[1]-hez (b) az azonos hivatkozás (azonos elnevemÉrzékelı[1] változó tartalma különbözik zés) ellenére a különbözı dobozok kü- a zóna[2]-höz tartozó mÉrzékelı[1] vállönbözı objektumokat reprezentálnak? tozó tartalmától. 4. Hogyan ábrázolja ez az objektumdiagSehogyan. E tény megjelenítésével a tervezı ram, hogy bizonyos érzékelık másképpen itt még egyáltalán nem foglalkozott. – A felnyugtázzák az üzemképességüket, mint adatleírásból tudjuk, hogy csak késıbb – az mások? érzékelık beszerzés során – fog kiderülni, hogy egy konkrét érzékelı történetesen milyen nyugtázási módot fog alkalmazni. Itt az ideje azon is elgondolkodni, mi következik abból a ténybıl, hogy ebben az esettanulmányban nem egy mőszaki rendszer számítógépes szimulációját kell kifejleszteni, hanem egy fizikailag létezı berendezés (hardver) vezérlı szoftverét. Az egyik lényeges következmény, hogy az általunk tervezett (és a 4.4. ábrán feltüntetett) objektumok nem azonosak az általuk képviselt – fizikailag létezı – hardverkomponensekkel. A 4.4. ábra objektumai csupán egy szoftver részei (szoftverobjektumok), amelyeknek az a dolguk, hogy az általuk képviselt hardverobjektummal kapcsolatot tartsanak, annak mőködését kövessék vagy vezéreljék. További járulékos következmény, hogy gondoskodni kell a szoftverobjektum és az általa képviselt hardverelem egyértelmő megfeleltetésérıl. Még jobb, ha a megfeleltetést egy olyan automatizmusra bízzuk, amely letapogatja, hogy milyen hardverkomponensek léteznek az adott konfigurációban, és csak a létezı hardverelemeknek megfelelı szoftverobjektumokat hoz létre. Tehát nem a tervezés során, hanem csak a futási idıben
128
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
dıl el, hogy pl. hány zóna objektum, illetve (a zónához kapcsoltan) milyen érzékelı objektumok lesznek a rendszerben. Arra is ki kell térni, hogy hogyan kommunikál egy szoftverobjektum a hozzákapcsolt hardverelemmel. – Feltételezzük, hogy annak a számítógépnek is van valamilyen operációs rendszere, amelyre a biztonsági rendszert vezérlı alkalmazásunkat ki akarjuk fejleszteni, és ez megkíméli az alkalmazás fejlesztıjét bizonyos mőszaki részletekkel való veszkıdéstıl. Például ha az érzékelıhardver (a fizikai érzékelı) passzív nyugtázó, akkor az érzékelı szoftverobjektum egy paraméterezett redszerhívással (az operációs rendszernek szóló hívással) tudja lekérdezni, hogy a megfelelı az érzékelıhardver üzemképes-e. Aktív nyugtázást alkalmazó érzékelıhardver nyugtázó üzenetetét pedig egy redszermegszakítás (az operációs rendszertıl érkezı megszakítás esemény) közli az érzékelı szoftverobjektummal. A fizikai érzékelıtıl érkezı riasztást szintén redszermegszakítás jelzi az érzékelı objektumnak. 4.3.2 Az objektumdiagramból elvonatkoztatott osztálydiagram Objektumdiagramot akkor készítünk, ha könnyebb abból elvonatkoztatva megszerkeszteni az osztálydiagramot. Nem állítjuk, hogy ez a körülmény itt is fennállna, de a 4.5. ábra akkor is jó példa egy, a 4.4. ábra szerinti objektumdiagramból elvonatkoztatható objektumdiagramra.
4.5. ábra: A 4.4. objektumdiagramból elvonatkoztatott osztálydiagram
Ellenırzı/magyarázó kérdések (a kérdések a 4.5. ábrára vonatkoznak): Ez az osztály tartalmazza azokat elemeket, 1. Miért jelenik meg a modellben a Mozamelyek mind a mozgásérzékelıkre, mind a gásÉrzékelı és a NyílásZáróÉrnyílászáróérzékelıkre értelmezhetık. Példázékelı osztályok általánosításaként az ul mindegyik érzékelınek látni kell azt a zóÉrzékelı osztály? nát, amelyiknek jelzi az érzékelt változást. 2. Nem lett volna elegendı csupán az Ér- A gépies válasz: Ilyen módon tudjuk kifejezni, hogy a kétféle érzékelı különbözı változékelı osztályt szerepeltetni a modell-
EGY LAKÁS BIZTONSÁGI RENDSZERE
129
zásokat érzékel, hogy a rendszernek eltérı módon kell reagálni a kétféle érzékelı jelzéseire. Azonban erre a kérdésre még visszatérünk, és látni fogjuk, hogy van olyan megoldás, amely mellett az említett célra példányszintő megkülönböztetés is elegendı, ahogyan a 3. fejezetben a zsebszámológép összeadás gombját is, és a szorzás gombját is ugyanabból a Gomb osztályból vettük. – Ráadásul azt is látni fogjuk, hogy az érzékelıknek az üzemképesség nyugtázása szempontjából való különbözısége inkább típusszintő jellemzı, pedig azzal eddig egyáltalán nem foglalkoztunk. 3. Ahogy a 4.4. ábra szerinti objektumdiA végeredmény tekintetében nincs különbagramon a kapcsolatok semelyik végükön ség. Az mÉrzékelı és az nyÉrzékelı az sem végzıdtek nyílban, úgy az osztálydiag- osztálymodell szerint is látja a zónát, de ezt ramon sem látható nyíl a Vezérlés és a a képességüket az osztálydiagramon nem az Kapcsoló közötti asszociáció, valamint a osztályuk és a Zóna osztály közötti asszociáVezérlés és a Zóna közötti asszociáció ció fejezi ki, hanem az Érzékelı és a Zóna végein. – Csakhogy a 4.4. ábrán a zóna és közötti asszociáció. Vagyis az említett képességet a MozgásÉrzékelı és a NyílásZáaz mÉrzékelı közötti, valamint a zóna és az nyÉrzékelı közötti kapcsolatokon róÉrzékelı osztályok az Érzékelı osztálytól öröklik meg. sem volt nyíl, ezzel szemben az osztálydiagramon a Zóna és a MozgásÉrzékelı, valamint a Zóna és a NyílásZáróÉrzékelı közötti asszociációk irányítottak. Mi az oka ennek a különbségnek? 4. Ha a modellezett rendszer 6 zónából áll, Emlékezzünk a feladat szövegére: „egy nagyobb lakásban a rendszer több zónából is akkor a Vezérlés és a Zóna közötti asszociáció zóna szerepnevő végén a szá- állhat”. Tegyük hozzá, hogy egy kisebb lamosság miért 1..*, miért nem egyszerően kás esetében pedig a zónák száma kevesebb is lehet. Egy zóna biztosan lesz, különben csak 6? nem beszélhetünk semmilyen biztonsági rendszerrıl. – Hasonló meggondolással adódott a kapcsolóTábla szerep 1..* számossága is. Hivatkozhattunk volna a rendszer mőködésére vonatkozó azon döntésünkre is, hogy a rendszeraz indításakor „letapogatja”, milyen hardver eszközök (fizikai zónák, fizikai kapcsolótáblák, fizikai érzékelık) érhetık el, és azoknak megfelelıen hozza létre a nekik megfelelı szoftverobjektumokat. 5. Miért lett az mÉrzékelı szerep és az A * felsı határ ugyanúgy magyarázható, nyÉrzékelı szerep számossága 0..*? mint a 4. kérdés válaszában a zóna számossága. (Lásd: „egy nagyobb épület nagyobb zónája több érzékelıvel is fel lehet szerelben? Mi tette szükségessé a MozgásÉrzékelı és a NyílásZáróÉrzékelı specializációk szerepeltetését?
130
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
ve”.) – De akkor miért nem 1..* a számosság, mint a zóna szerep esetében? Válasz: Az is lehetne. Vizsgán el kellene fogadni a vizsgázó ilyen döntését, mert a feladat szövegének nem mond ellent. Egyedül a modellezı azon gondolata játszott szerepet, hogy miért ne engedhetnénk meg, hogy valamely zónában csak mozgásérzékelı legyen, és akkor a nyílászáróérzékelık száma 0. Hasonlóan elképzelhetı olyan zóna is, amelyben csak nyílászáróérzékelık vannak, és akkor ott a mozgásérzékelık száma 0. Azt a tényt, hogy a zónának legalább egy 6. Az mÉrzékelı és az nyÉrzékelı érzékelı mindenképpen jelezni fog valamiszerepek 0..* számosságából arra lehet lyen változást, az Érzékelı osztály és a következtetni, hogy lehet olyan zóna is, Zóna osztály közötti asszociációnak az amelyhez egyetlen érzékelı sem tartozik. Azonban csak olyan zónának van értelme, Érzékelı felıli végéhezt tartozó 1..* amely legalább egy érzékelıt tartalmaz számosság fejezi ki. Azt pedig, hogy ez nem (mert az különben semmilyen biztonsági lehet egy haramadik típusú érzékelı, a funkciót nem tud betölteni). Az utóbbi megjegyzés dobozban látható megszorítás meggondolással egyezı megkötést mi rep- garantálja. (Merthogy aszerint a kétféle rezentálja a diagramon? specializáció – mármint a MozgásÉrzékelı és a NyílásZáróÉrzékelı osztály – kimeríti az Érzékelı példányhalmazát.) 7. Tudjuk, hogy a szerepnevekbıl a megva- Az egyik lehetséges megoldást a 4.6. ábra lósítás során attribútumok lesznek. Igen mutatja: A Vezérlés osztály szerkezetéám, de mi van akkor, ha a szerepnév száben a kapcsolóTábla nem egy skalár mossága 1-nél nagyobb is lehet, mint pélattribútum, hanem egy többelemő vektor, dául a kapcsolóTábla szerepnév 1..* amelynek elemei az 1-tıl kTáblaSzámig számossága? terjedı indexekkel különböztethetık meg, azaz így hivatkozhatók: kapcsolóTábla[1], kapcsolóTábla[2], …, kapcsolóTábla[kTáblaSzám]. Hasonlóan a zóna sem skalár attribútum a Vezérlés osztály szerkezetében, hanem egy vektor amelynek elemei: zóna[1], zóna[2], …, zóna[zónaSzám]. Akár a kTáblaSzám, akár a zónaSzám példányonként különbözı lehet, azaz akkor rögzítıdik, amikor a Vezérlésnek létrehozzuk egy-egy új példányát. Ezek értékei a példányt létrehozó konstruktor paramétereiként adhatók meg. – Hasonló megoldások alkalmazhatók a Zóna osztály szerkezetében az mÉrzékelı és az nyÉrzékelı attribútumokra.
EGY LAKÁS BIZTONSÁGI RENDSZERE
131
4.6. ábra: A Vezérlés és a Zóna osztályok részletesebb definíciója
4.3.3 A MozgásÉrzékelı és a NyilásZáróÉrzékelı specializációk Az elıbbi szakaszban kapott statikus modell még több okból nem számít végleges változatnak. Az egyik ok természetesen az, hogy még hátra van a probléma dinamikus modellezése, amely során feltárt tények általában új elemek bevezetésének szükségességére mutatnak rá. Itt azonban konkrétan egy olyan kérdésre térünk vissza, amelyet az elızı szakaszban már feltettünk, de az érdemi megválaszolását késıbbre halasztottuk. Egy kérdés-válasz páros másolata a 4.3.2. szakaszból: 2. Nem lett volna elegendı csupán az A gépies válasz: Ilyen módon tudjuk kifejezni, Érzékelı osztályt szerepeltetni a mo- hogy a kétféle érzékelı különbözı változásokat érzékel, hogy a rendszernek eltérı módon kell dellben? Mi tette szükségessé a Mozreagálni a kétféle érzékelı jelzéseire. gásÉrzékelı és a NyílásZáróAzonban erre a kérdésre még visszatérünk, és Érzékelı specializációk szerepeltelátni fogjuk, hogy van olyan megoldás, amely tését? mellett az említett célra példányszintő megkülönböztetés is elegendı, ahogyan a 3. fejezetben a zsebszámológép összeadás gombját is, és a szorzás gombját is ugyanabból a Gomb osztályból vettük. – Ráadásul azt is látni fogjuk, hogy az érzékelıknek az üzemképesség nyugtázása szempontjából való különbözısége inkább típusszintő jellemzı, pedig azzal eddig egyáltalán nem foglalkoztunk.
132
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
A „gépies válaszban” a MozgásÉrzékelı és a NyílásZáróÉrzékelı specializációk szerepeltetésének egyik indoka az volt, hogy a kétféle érzékelı különbözı változásokat érzékel (a mozgásérzékelı valamilyen mozgást, a nyílászáró érzékelı pedig valamelyik ablak vagy ajtó kinyitását). Azonban emlékeztetünk rá, hogy az általunk tervezett érzékelı objektum nem azonos a vele kapcsolt érzékelı hardverrel., ennek következtében az itt tervezett szoftver szempontjából közömbös, hogy a fizikai érzékelı hogyan mőködik, neki csak az a lényeg, hogy egy (fizikai) nyílászáróérzékelıvel kapcsolatot tartó nyílászáróérzékelı (szoftver)objektumtól érkezı jelzés (üzenet) megkülönböztethetı legyen egy (fizikai) mozgásérzékelıvel kapcsolatot tartó mozgásérzékelı (szoftver)objektumtól érkezı jelzéstıl (üzenettıl). A megkülönböztetésre két módunk van: • Az üzeneteket a nevükben különböztetjük meg. A mozgásérzékelı (szoftver)objektum riasztásM() üzenetet, a nyílászáróérzékelı objektum pedig riasztásNy() üzenetet küld a rendszernek. • Az üzenetek neve azonos, de bennük különbözı paraméterek adódnak át. Például mozgásérzékelı (szoftver)objektum riasztás(1) üzenetet, a nyílászáróérzékelı objektum pedig riasztás(2) üzenetet küld a rendszernek. Pontosabban a rendszer mindkettıtıl riasztás(érzékelıTípus) üzenetet kap, amelyben az érzékelıTípus paraméter értéke egyik esetben 1, a másikban 2. A két megoldás látszatra apró formai jegyekben való eltérése messzemenı következményekkel jár mind az üzenetet küldı, mind az azt kapó objektumnál. (Az utóbbi az az zóna objektum, amelyhez az érzékelı objektum kapcsolódik.) • Ha az üzenetek a nevükben térnek el, akkor az olyan típusszintő megkülönböztetésre ad lehetıséget, amelyet már a fordítóprogram egyszer s mindenkorra érvényesíteni tud, és ez futási idıben megtakarítást fog jelenteni. – Igazából ez a meggondolás indokolhatja a MozgásÉrzékelı és a NyílásZáróÉrzékelı specializációk bevezetését. • Ha az üzenetek neve azonos (és a az üzenetet kapó objektum számára a paraméter neve is azonos), akkor a mozgásérzékelı és a nyílászáróérzékelı (szoftver)objektumokat elegendı példányszinten megkülönböztetni, azaz nincs különösebb értelme a MozgásÉrzékelı és a NyílásZáróÉrzékelı specializációk bevezetesének. Ez is korrekt megoldás, de hátránya, hogy az üzenetet kapó objektumnak futási idıben kell újra és újra tesztelnie az érzékelıTípus paraméter értékét. – A példányszintő megkülönböztetés azt jelenti, hogy csak egy Érzékelı osztály van, amely rendelkezik egy érzékelıTípus példányattribútummal. Ez minden érzékelı objektum létrehozásakor azonnal értéket kap: mozgásérzékelık esetében mondjuk 1-es értéket, a nyílászáróérzékelık esetében pedig 2-es értéket. A rendszer mőködése alatt pedig mindegyik érzékelı, amikor riasztania kell a rendszert, a saját érzékelıTípus attribútumának értékét adja át a riasztás(érzékelıTípus) üzenet paraméterében. Megjegyzés: Rossz tervezık / programozók számára elképzelhetı harmadik megoldás is. Hogy az itt elıadottak érthetıbbek legyenek, pszeudokódú példák útján is magyarázatot adunk rájuk. Azzal a megoldással kezdjük, amely a mozgásérzékelı és a nyílászáróérzékelı objektumokat csak példányszinten különbözteti meg. (A pszeudokódban a … tartalmú sorok jelzik, hogy az adott helyen további attribútumok vagy további mőveletek lennének, de azokkal egyelıre nem foglalkozunk.)
EGY LAKÁS BIZTONSÁGI RENDSZERE
133
// Az érzékelıket csak példányszinten megkülönböztetı megoldás OSZTÁLY Zóna { vezérlés: Vezérlés; távozássalÉlesítve: boolean := false; otthonTartÉlesítve: boolean := false; ... // Az érzékelı objektumok ezen osztály példányainak küldik a riasztás // üzeneteket. Tehát ezen osztály definícióján belül kell lenni egy, // a riasztás üzenetre reagáló riasztás(…) metódusnak. riasztás(érzékelıTípus:int): void { // Ha a zóna otthon tartózkodásra van élesítve, akkor tesztelnie kell // az érzékelıTípus értékét, mert akkor csak a nyílászáróérzékelıtıl // érkezı riasztást kell figyelembe vennie. HA távozássalÉlesítve VAGY (otthonTartÉlesítve ÉS érzékelıTípus = 2) AKKOR { // Az érzékelıTípus = 2 teszt jelent plusz terhet futási idıben. vezérlés.riasztás() } } ... } OSZTÁLY Érzékelı { zóna: Zóna; érzékelıTípus: int;
// // // //
Ez a példány létrehozásakor 1-es vagy 2-es értéket kap. Mozgásérzékelınél 1-est. Nyílászáróékelınél 2-est.
... // Ebben is van riasztás() metódus, amelynek az a dolga, hogy a // fizikai érzékelıtıl érkezı riasztást jelzı rendszermegszakítás // esetén riasztás(…) üzenetet küldjön az általa látott zónának. riasztás(): void { zóna.riasztás(érzékelıTípus) } ... }
Most következzék a mozgásérzékelı és a nyílászáróérzékelı objektumokat típusszinten megkülönböztetı megoldás pszeudokódja. // Az érzékelıket típusszinten megkülönböztetı megoldás OSZTÁLY Zóna { vezérlés: Vezérlés; távozássalÉlesítve: boolean := false; otthonTartÉlesítve: boolean := false; ... // Az érzékelı objektumok ezen osztály példányainak küldik // a riasztásM(), illetve riasztásNy() üzeneteket. // Tehát ezen osztály definícióján belül kell lenni az üzenetekre // reagáló riasztásM(), illetve riasztásNy() metódusnak. riasztásM(): void { HA távozássalÉlesítve AKKOR vezérlés.riasztás() // Itt nincs szükség a // VAGY (otthonTartÉlesítve ÉS érzékelıTípus = 2) // tesztre. }
134
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
riasztásNy(): void { HA távozássalÉlesítve VAGY otthonTartÉlesítve AKKOR vezérlés.riasztás() // Itt nincs szükség az érzékelıTípus = 2 tesztre. } ... } ABSZTRAKT OSZTÁLY Érzékelı {} zóna: Zóna; ... ABSZTRAKT riasztás(): void; ... } OSZTÁLY MozgásÉrzékelı SZÜLİJE Érzékelı { ... // Ebben is van riasztás() metódus, amelynek az a dolga, hogy a // fizikai érzékelıtıl érkezı riasztást jelzı rendszermegszakítás // esetén riasztásM(…) üzenetet küldjön az általa látott zónának. riasztás(): void { zóna.riasztásM() } ... } OSZTÁLY NyílásZáróÉrzékelı SZÜLİJE Érzékelı { ... // Ebben is van riasztás() metódus, amelynek az a dolga, hogy a // fizikai érzékelıtıl érkezı riasztást jelzı rendszermegszakítás // esetén riasztásNy(…) üzenetet küldjön az általa látott zónának. riasztás(): void { zóna.riasztásNy() } ... }
Ellenırzı/magyarázó kérdések (a kérdések a pszeudokódú példákra vonatkoznak): Ez a 4.5. ábra osztálydiagramból követke1. Mibıl adódik a Zóna osztály vezérzik. Azon a Zóna és a Vezérlés osztályok lés nevő és Vezérlés típusú attribútuközötti asszociációnak a vezérlés szerepma? nevébıl adódik. Mivel a dinamikus modellezésnél még nem 2. Milyen célt szolgálnak a Zóna osztály tartunk, az Olvasónak ezen attribútumok távozássalÉlesítve nevő és ottszerepére egyelıre csak a 4.1. alfejezetben honTartÉlesítve nevő attribútumai? olvasható feladatleírás szolgálhat magyarázattal. A távozássalÉlesítve attribútum true értéke jelzi, ha a rendszert távozással élesítették. Az otthonTartÉlesítve attribútum true értéke jelzi, ha a rendszert otthon tartózkodással élesítették. A feladatleírásból adódóan ezeket az eseteket (állapotokat) azért kell megkülönböztetni, mert otthon tartózkodással élesítés esetén csak a nyílászáróérzékelık által jelzett változások miatt kell riasztani a rendszernek.
EGY LAKÁS BIZTONSÁGI RENDSZERE 3. Mit jelent a Zóna osztály távozássalÉlesítve nevő és otthonTartÉlesítve nevő attribútumainak a false kezdı értéke? 4. A pszeudokódban a riasztás( érzékelıTípus) metódust sehol nem elızi meg távozássalÉlesítve:= true értékadás. Akkor a metóduson belül miért kell vizsgálni a távozássalÉlesítve feltételt?
135
Azt, hogy minden Zóna-példány nem élesített állapotban jön létre.
Nem azt kell nézni, hogy a pszeudokód szövegében, hanem azt, hogy a zóna mőködése alatt idıben megelızheti az említett értékadás a feltételvizsgálatot. – Ez a feltételvizsgálat arra kérdez rá, hogy (idıben) megelızıen olyan élesített állapotba került-e a zóna, amelyben az adott típusú érzékelıtıl érkezı riasztást továbbítania kell a rendszernek. 5. Az érzékelı miért a zónát riasztja, miért Mert az érzékelı a zónához csatlakozik nem a vezérlést? közvetlenül, nem a vezérléshez (lásd a 4.4. objektumdiagramot vagy a 4.5 osztálydiagramot). 6. A vezérlés.riasztás() utasítás- Mert a vezérlésnek már mindegy, hogy meban miért nincs paramétere a riasztás() lyik érzékelıtıl, illetve milyen típusú érzékelıtıl érkezik a riasztás. üzenetnek? (A 4.4.3. szakaszban lesznek olyan megfontolások, amelyek szerint azt viszont jó lenne tudni a vezérlésnek, hogy melyik zónától jön a riasztás, de ott még nem tartunk.) 7. Hogyan lehetséges, hogy a MozgásÉrzé- Úgy lehetséges, hogy a MozgásÉrzékelı kelı osztály riasztás() metódusában álosztály az Érzékelı osztály leszármazottló zóna.riasztásM() utasítás szerint a ja, tehát attól megörökli a zóna pédányattMozgásÉrzékelı-példány egy zóna ob- ribútumot. jektumnak küld üzenetet, pedig a MozgásÉrzékelı osztály definíciójában nincs is olyan zóna attribútum, amely valamely Zóna-példányra mutatna? 4.3.4 Az érzékelık üzemképesség-nyugtázási módjának figyelembe vétele
A 4.1 feladatleírásból származik a következı idézet: „megengedjük, hogy az üzemképesség nyugtázása szempontjából kétféle érzékelı legyen a rendszerben, méghozzá függetlenül attól, hogy mozgásérzékelırıl vagy nyílászáróérzékelırıl van-e szó: Az egyik fajta csak akkor nyugtáz, ha a rendszer lekérdezi, a másik rendszeres idıközönként (pl. másodpercenként nyugtázó jelet küld a rendszernek.” – Megállapíthatjuk, hogy a feladatleírás ezen részét a 4.5. osztálydiagram figyelmen kívül hagyta, de most a modell éppen ezen hiányossága megszüntetésének módjain fogunk elgondolkodni. Mindenekelıtt emlékeztetünk rá, az érzékelıknek azért kell nyugtázni az üzemképes állapotukat, mert ennek hiányában a rendszer nem képes érzékelni azt a vészeseményt, amikor a riasztót levágják a rendszerrıl. Persze, ha a biztonsági rendszer tervezıje a szakmája által igényelt szinten paraniod, akkor a lehetséges veszélyeket tovább gondolja, például így: 1. Mi van, ha a betörı rendelkezik egy olyan kütyüvel, amely ugyanolyan nyugtázó jelet képes küldeni, mint az érzékelı? Ennek birtokában a betörı elıbb rákötheti azt a
136
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK kütyüt az érzékelı és a rendszer közötti kábelre (az érzékelıvel párhuzamosan), és ha csak azután vágja le onnan az érzékelıt, a rendszer nem fogja észrevenni a változást. – Nehezítsük meg a betörı dolgát – gondolja. Legyen minden érzékelınek hardverszinten (fizikai szinten) beállított egyedi azonosítója, és azt küldje el a rendszernek a nyugtázó jelben (nyugtázó válaszban). 2. De mi van, ha a betörı olyan kütyüvel is rendelkezik, amely az elektronikusan küldött nyugtázó jelet le tudja olvasni, és az érzékelı helyettesítésére való kütyüt be tudja állítani a leolvasott jel küldésére? – Nehezítsük tovább a betörı dolgát! – Az érzékelı idıben változó nyugtázó üzenetet küldjön a rendszernek, amelyet egy algoritmus az elızı üzenetbıl, a fizikai azonosítóból és egy titkos kulcskódból állít elı. 3. De mi van, ha …?
Az esettanulmánynak nem az a célja, hogy a biztonsági rendszerek témájában szakértıvé képezze ki az Olvasót, ezért a fenti számozott fokozatok közül már az elsıvel megelégszünk; vagyis csak azzal teszünk egy halvány gesztust a betörık dolgának megnehezítése irányába, hogy a rendszerünk a nyugtázó jelben a fizikai azonosítót (is) várja a fizikai erzékelıtıl. Az érzékelıknek az üzemképesség nyugtázási mód szerinti osztályozása nem önmagában érdekes, hanem azzal a ténnyel együtt, hogy ez az osztályozás független a mozgásérzékelıket és a nyílászáróérzékelıket megkülönböztetı osztályozástól. A független osztályozások (egymástól független specializációk) kezelése a kezdı tervezı számára több csapdát rejt. Nem az a probléma, hogy nehéz megoldást találni; éppen ellenkezıleg: a logikailag lehetséges kombinációk számos megoldást kínálnak, amelyek közül – gyakorlat hiányában vagy az OO technológia félreértelmezése esetén – a legalkalmasabb (a legelegánsabb) megoldást nehéz kiválasztani. De hát nem lehet, hogy itt egy mesterségesen felfújt problémáról van szó? – Ha az Érzékelı osztályból nem származtatunk le semmilyen alosztályokat, hanem csak példányszinten különböztetjük meg az érzékelıket egy érzékelıTípus és egy nyugtázásTípus attribútum bevezetésével (lásd a 4.7. ábra szerint definiált Érzékelı osztályt), azzal átvágható a gordiuszi csomó: Ha nincs semmilyen specializáció, akkor eltőnik a független specializációk kezelésének problémája is. Bár a 4.3.3. szakasz megmutatta, hogy az érzékelı példányszintő típizálása, azaz a típusszintő specializáció hiánya a futási idıben plusz ráfordításokkal jár (és programozási idıben is több figyelmet igényel a programozótól), ám a 4.3.3. szakaszban még csak egyféle alosztályozásról (a mozgásérzékelık és a nyílászáróérzékelık megkülönböztetésérıl) volt szó. Nem éppen az indokolná-e, hogy most mégis ellenkezı megoldást válasszunk, mert kétféle (egymástól független) szempontú specializációt már körülményes kezelni?
4.7. ábra: A specializáció nélküli Érzékelı osztály
A kérdésre könnyebb lesz válaszolni, ha egy kicsit elmerülünk a 4.7. ábra szerinti Érzékelı osztály definíciójának pszeudokódú részletezésében. De mielıtt ezt megtennénk, ki kell térnünk a 4.7. ábrán látható néhány olyan attribútum és metódus értelmezésére, amelynek a létezésére az esettanulmány korábbi szakaszai nem szolgáltak magyarázattal.
EGY LAKÁS BIZTONSÁGI RENDSZERE fizikaiAzonosító:
nyugtázásTípus:
utolsóNyugtázás:
idıKöz:
getÜzemképes():
nyugtázóJelFogadás():
137
Olyan számkód, amellyel a fizikai érzékelı az üzemképességét nyugtázó üzenetben / válaszban azonosítja magát. – Indoklásul lásd a jelen szakasz elejét! Ha nyugtázásTípus=1, akkor az a fizikai érzékelı, amellyel az érzékelı szoftverobjektum kapcsolatot tart, aktív nyugtázást végez, azaz rendszeres idıközönként az üzemképességét nyugtázó üzenetet küld a rendszernek (az érzékelı szoftverobjektumnak). Ha nyugtázásTípus=2, akkor a fizikai érzékelı passzív nyugtázást végez, azaz csak a rendszer (az érzékelı szoftverobjektum) kérdésére adott válaszban nyugtázza az üzemképességét. Csak aktív nyugtázás esetén használatos. Az érzékelı szoftverobjektum ebben jegyzi fel, a vele kapcsolt fizikai érzékelıtıl küldött mindenkori utolsó nyugtázó üzenet idıpontját. Csak aktív nyugtázás esetén használatos. Ha az utolsóNyugtázás tartalma az idıKöz attribútumban adott számú másodperccel régebbi annál az idıpontnál, amelyben az érzékelı szoftverobjektumnak válaszolni kell a rendszer (a zóna) által hozzáintézett getÜzemképes() kérdésére, akkor az érzékelı szoftverobjektum egy false válasszal üzemképtelenséget fog visszajelezni. A 4.7. ábrán az aláhúzás azt jelzi, hogy ez egy osztályattribútum. – Ez a megoldás azt feltételezi, hogy az összes aktív nyugtázást végzı fizikai érzékelıre ugyanaz az idıKöz érték alkalmazható. Az érzékelı szoftverobjektum ezzel a metódussal (függvénnyel) válaszol a zóna ugyanilyen nevő kérdésére. A true visszaadott érték üzemképességet jelez, a false az ellenkezıjét. 1. megjegyzés: A zóna nézıpontjából minden érzékelı passzív nyugtázó, mert ı nem a fizikai érzékelıket, hanem az érzékelı szoftverobjektumokat látja. a fizikai érzékelık aktív / passzív nyugtázó volta csak az érzékelı szoftverobjektumokat érinti. 2. megjegyzés: Ennek a mőveletnek egy aktív nyugtázó fizikai érzékelıvel kapcsolt érzékelı szoftverobjektum esetében más a megvalósítása, mint egy passzív nyugtázó fizikai érzékelıvel kapcsolt érzékelı objektum esetében. – Errıl a mővelet megvalósításának pszeudokódja többet fog mondani. Csak aktív nyugtázás esetén használatos. Az érzékelı szoftverobjektum ezzel a mővelettel reagál a vele kapcsolt fizikai érzékelı által elıidézett rendszermegszakításra (nyugtázó üzenetre): ellenırzi az üzenetben küldött fizikai azonosítótt, és az üzenet idıpontját beírja az utolsóNyugtázás attribútumba.
138
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
nyugtázóVálasz():
Csak passzív nyugtázás esetén használatos. Az érzékelı szoftverobjektum e mővelet (függvény) megvalósításában egy (az operációs rendszernek szóló) rendszerhívás útján üzemképességet tesztelı kérdést intéz a fizikai érzékelıhöz, és ha megfelelı nyugtázó választ kap, akkor ez a függvény true, egyébként pedig false értéket ad vissza. Ezt a függvényt mind a nyugtázóJelFogadás(), mind a nyugtázóVálasz() használja. Az a rendeltetése, hogy a fizikai érzékelıtıl rendszermegszakítás vagy rendszerhívás útján érkezı nyugtázó üzenetben / válaszban foglalt fizikai azonosítót visszaadja.
kapottAzonosító():
Ezek után következhet a 4.7. ábra szerinti Érzékelı osztály pszeudokódú definíciója. Ebben a 4.3.3. szakaszban adott definícióhoz képest újnak számító elemeket vastagabb szedés és nagyobb betőméret emeli ki. OSZTÁLY Érzékelı { zóna: Zóna; érzékelıTípus: int;
// // // //
Ez a példány létrehozásakor 1-es vagy 2-es értéket kap. Mozgásérzékelınél 1-est. Nyílászáróékelınél 2-est.
// Specializáció esetén // erre nincs szükség!!!!!! fizikaiAzonosító: int; nyugtázásTípus: int; // Ez a példány létrehozásakor // 1-es vagy 2-es értéket kap. // Aktív nyutázás esetén 1-est. // Passzív nyugtázás esetén 2-est. // Specializáció esetén erre nincs // szükség!!!!!! utolsóNyugTázás: Time; OSZTÁLYATTRIBÚTUM idıKöz: int:=2; // Ez a riasztás() metódus kapja el a fizikai érzékelıtıl érkezı // riasztást jelzı rendszermegszakítást riasztás(): void { zóna.riasztás(érzékelıTípus) // Specializáció esetén erre
// a paraméterre nincs szükség. }
getÜzemképes(): boolean { HA nyugtázásTípus=1 AKKOR { // Specializáció esetén erre // nincs szükség!!!!!! HA másodperc(most(), utolsóNyugtázás) < idıKöz AKKOR VISSZATÉR true ELSE VISSZATÉR false } KÜLÖNBEN VISSZATÉR nyugtázóVálasz() }
EGY LAKÁS BIZTONSÁGI RENDSZERE
139
// Ez metódus kapja el azt a rendszermegszakítást, amely // a kapcsolódó fizikai érzékelıtıl jött nyugtázást jelzi. PRIVÁT nyugtázóJelFogadás(): void { HA kapottAzonosító()=fizikaiAzonosító AKKOR utolsóNyugtázás:=most() } // Ez metódus kérdezi le egy rendszerhívással // a kapcsolódó fizikai érzékelı üzemképességét. PRIVÁT nyugtázóVálasz(): boolean { // A ... helyén egy nem részletezett rendszerhívás. ...
HA kapottAzonosító()=fizikaiAzonosító AKKOR VISSZATÉR true KÜLÖNBEN VISSZATÉR false } PRIVÁT kapottAzonosító(): int { // A rendszermegszakítás vagy rendszerhívás útján kapott // nyugtázó üzenetbıl visszadja az érzékelı azonosítóját. ...
} // A 4.7.ábrával ellentétben itt megadjuk a konstruktort is. Érzékelı(pZóna: Zóna, pÉrzékelıTípus: int, // Specializáció esetén // erre nincs szükség!!! pFizikaiAzonosító: int, pNyugtázásTípus: int) // Specializáció esetén // erre nincs szükség!!! { zóna := pZóna; érzékelıTípus := pÉrzékelıTípus; // Specializáció esetén // erre nincs szükség!!! fizikaiAzonosító := pFizikaiAzonosító; nyugtázásTípus := pNyugtázásTípus // Specializáció esetén // erre nincs szükség!!! } }
A fenti pszeudokód tartalmaz két osztályfüggetlen függvényt: • Az egyik a most() függvény, amely egy Time típusú értéket, az éppen aktuális idıt adja vissza másodperc pontossággal. • A másik a másodperc(p1: Time, p2: Time) függvény, amely a két Time típusú paraméter különbségét másodpercben adja vissza. Most visszatérünk ahhoz a kérdéshez, hogy az érzékelı modellezését miért ne lehetne letudni mindenféle specializáció nélkül a 4.7. ábrán, valamint a fenti pszeudokóddal definiált Érzékelı osztállyal. Egyidejőleg igazak a következı megállapítások: •
A specializáció nélküli Érzékelı osztály a mőködıképesség tekintetében korrekt megoldás, de nem minden tekintetben optimális (lásd a felsorolás következı elemeit).
140
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK •
Ez a megoldás a programozótól több figyelmet kíván, mint a specializációt alkalmazó megoldások. A programozónak gondoskodni kell mindazon kódelemekrıl, amelyeket a pszeudonyelvő leírásban „Specializáció esetén erre nincs szükség!!!” megjegyzés kísér.
•
Az említett megjegyzéssel kísért feltételvizsgálatok futási idıben is plusz ráfordítást jelentenek. Ráadásul (amint azt már a 4.3.3. szakaszban láttuk) ez a plusz ráfordítás nem csak az érzékelı objektumoknál, hanem az általuk riasztott zóna objektumoknál is jelentkezik.
Ellenırzı/magyarázó kérdések: 1. Az idıKöz miért le(hete)tt osztályattribútum?
2. A nyugtázóJelFogadás(), a nyugtázóVálasz() és a kapottAzonosító() mőveletek miért le(he)ttek privát minısítésőek? 3. A pszeudokódú leírás szerint az aktív nyugtázást végzı érzékelıknél legfeljebb mennyi lehet az aktuális idı és az utolsóNyugtázás különbsége?
4. Mennyi lehet ugyanez a passzív nyugtázást végzı érzékelıknél? 5. A 4.3.1. szakaszban volt arról szó, hogy gondoskodni kell az érzékelı szoftverobjektum és az általa képviselt érzékelıhardver egyértelmő megfeleltetésérıl. – Nem pont az Érzékelı konstruktorában kellene errıl a megfeleltetésrıl intézkedni? – Egyáltalán mit jelent ezek összekapcsolása?
Mert az aktuális idı (a pszeudokódban: most()) és az utolsóNyugtázás közötti különbség felsı korlátja példányonként nem különbözik, azt tehát elegendı egyszer, az osztálynál megadni. Mert ezek végrehajtására az Érzékelıpéldány önmagát szólítja fel (például az elsı kettıre a getÜzemképes() mővelet végrehajtása közben). Kevesebb, mint 2 másodperc. Ez az OSZTÁLYATTRIBÚTUM idıKöz: int:=2;
és a HA másodperc(most(), utolsóNyugtázás) < idıKöz AKKOR VISSZATÉR true
utasításokból látszik. Azoknál az utolsóNyugtázás attribútum nem használatos. A válasz némileg hosszabb, ezért a táblázat után következik.
Arról, hogy csak a ténylegesen létezı fizikai zónák és fizikai érzékelık képviseletére jöjjenek létre szoftverobjektumok, és éppen az egymásnak megfelelı fizikai objektumok és szoftverobjektumok kapcsolódjanak össze, például az alábbi módon lehet gondoskodni: 1. A vezérlés rendszerhívással lekérdezi az operációs rendszertıl, hogy milyen fizikai zónák léteznek. Az operációs rendszer visszaadja a létezı fizikai zónák egyedi csatornakódjainak listáját. (A csatornakód a fizikai zóna olyan hivatkozása, amely azt az operációs rendszernél azonosítja.) A vezérlés a létezı fizikai zónák mindegyikéhez létrehoz egy zóna szoftverobjektumot, amellyel közli a neki megfelelı fizikai zóna csatornakódját. 2. A zóna újabb rendszerhívással lekérdezi az operációs rendszertıl hogy milyen fizikai érzékelık „lógnak” a neki megfelelı (adott csatornakódú) fizikai zónán. Az operációs rendszer visszaadja a létezı fizikai érzékelık egyedi alcsatornakódjainak listáját.
EGY LAKÁS BIZTONSÁGI RENDSZERE
141
3. Az érzékelıknek itt tárgyalt – specializációk nélküli – változatában az eljárás folytatódhatna úgy is, hogy a zóna a létezı fizikai érzékelıinek mindegyikéhez létrehoz egy érzékelı szoftverobjektumot, amellyel közli a neki megfelelı fizikai érzékelı alcsatornakódját; és ettıl kezdve az érzékelı objektum ad ki olyan rendszerhívásokat, amellyel • kideríti az érzékelt változás típusát (érzékelıTípus), • kideríti az üzemképesség nyugtázásának módját (nyugtázásTípus), • kideríti a nyugtázó üzenetben / valaszban közölt fizikai azonosítót (fizikaiAzonosító), • regisztrálja magát az operációs rendszernél mint a fizikai érzékelıtıl érkezı riasztás (vagy aktív nyugtázás) miatti rendszermegszakítás címzettjét. 4. Azonban az érzékelık (típusszintő) specializációja esetében a 3. pont alatti megoldás nem mőködik, mert az érzékelt változás típusának és / vagy az üzemképesség nyugtázási módjának már az érzékelı objektum létrehozása elıtt ismertnek kell lennie. Ezért inkább azt a megoldást választjuk, hogy a 3. pontban felsorolt teendıket a zóna objektum végzi el, az elsı hármat az érzékelı objektum létrehozása elıtt, a negyediket pedig utána. – Ez magyarázza, hogy az Érzékelı konstruktorában semmi nyoma nincs a 3. pontban felsorolt mőveleteknek. – Ilyen megoldás mellett az új érzékelı objektum a konstruktora pÉrzékelıTípus, pNyugtázásTípus, pFizikaiAzonosító paramétereiben értesül a kapcsolt fizikai azonosító jellemzıirıl. A következı szakaszok a specializáció különbözı változatait tekintik át. 4.3.5 Az érzékelık specializációja csupán az érzékelt változás típusa szerint Az érzékelık specializációja tekintetében a 4.8. ábrán mutatott modell csak abban különbözik a 4.5. ábra modelljétıl, hogy számol a nyugtázás módjának alternatíváival, de egyébként ez is csak az érzékelt változások típusára alapozott specializációt alkalmaz. – A nyugtázás módját csupán példányszinten különbözteti meg, ahhoz hasonlóan, mint a 4.7. ábra modellje. A 4.3.3. szakaszban már láttuk, hogy ez a specializáció feleslegessé teszi az érzékelıTípus nevő attribútumot, és az érzékelık által küldött riasztásüzenetekben az ugyanilyen nevő paramétert, így az üzenetet kapó zónákat sem terheli a paraméter tesztelésének mővelete. Ennél a modellnél az Érzékelı osztály definíciójában a riasztás() mővelet absztrakt, mert ahhoz csak az alosztályoknál rendelıdik megvalósítás. Ennek következtében az Érzékelı osztály is absztrakt lett. Bıvebb információval a pszeudokódú leírás szolgál. 4.8. ábra: Csak az érzékelt változás típusa szerinti specializáció
142
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
ABSZTRAKT OSZTÁLY Érzékelı { zóna: Zóna; fizikaiAzonosító: int; nyugtázásTípus: int; utosóNyugtázás: Time; OSZTÁLYATTRIBÚTUM idıKöz: int ABSZTRAKT riasztás(): void; getÜzemképes(): boolean { // Mint a 4.3.4. szakaszban. } PRIVÁT nyugtázóJelFogadás(): void { // Mint a 4.3.4. szakaszban. } PRIVÁT nyugtázóVálasz(): boolean { // Mint a 4.3.4. szakaszban. } PRIVÁT kapottAzonosító(): int { // Mint a 4.3.4. szakaszban. } // A következı mővelet a 4.8. ábrán nem szerepelt, mert csak // a konstruktorok szerkesztése tette nyilvánvalóvá, hogy erre is // szükség van. PRIVÁT közösKezdetiBellítás(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: int) // Ha a nyugtázási módra is lenne // specializáció, erre nem lenne szükség!!! : void { // Olyan kezdeti beállító utasításokat tartalmaz, amelyek ismétlését // szeretnénk elkerülni a leszármazott osztályok konstruktoraiban. zóna := pZóna; fizikaiAzonosító := pFizikaiAzonosító; nyugtázásTípus := pNyugtázásTípus // Ha a nyugtázási módra is // lenne specializáció, akkor // erre nem lenne szükség!!! } } OSZTÁLY MozgásÉrzékelı SZÜLİJE Érzékelı { riasztás(): void { zóna.riasztásM() } // A 4.8.ábrával ellentétben itt megadjuk a konstruktort is. MozgásÉrzékelı(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: int) // Ha a nyugtázási módra is lenne // specializáció, erre nem lenne szükség!!! { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pNyugtázásTípus); } } OSZTÁLY NyílásZáróÉrzékelı SZÜLİJE Érzékelı { riasztás(): void { zóna.riasztásNy() } // A 4.8.ábrával ellentétben itt megadjuk a konstruktort is. NyílásZáróÉrzékelı(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: int) // Ha a nyugtázási módra is lenne // specializáció, erre nem lenne szükség!!! { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pNyugtázásTípus); } }
EGY LAKÁS BIZTONSÁGI RENDSZERE Ellenırzı/magyarázó kérdések: 1. A 4.8. ábrán az Érzékelı osztály neve miért dılt betővel látszik. 2. Ha az Érzékelı osztály absztrakt osztály, akkor hogyan tartalmazhat konkrét mőveleteket (pl. getÜzemképes())?
143
Mert az UML-ben ez jelzi az absztrakt osztályt. Miért ne tartalmazhatna? Egy osztály nem azért absztrakt, mert minden mővelete absztrakt, hanem azért mert legalább egy mővelete (pl. a riasztás() mővelet) az.
Az itteni pszeudokódban már nincsenek jelen azok a részek, amelyeket az érzékelt változás típusa szerinti specializáció feleslegessé tett, de még mindig több megjegyzés azonosít olyan kódrészeket, amelyekre akkor nem lenne szükség, ha egyidejőleg a nyugtázási mód szerinti specializációval is élnénk. – A 4.3.7. szakasztól kezdedıen ilyen megoldásokra is sort kerítünk, de elıbb még kitérünk arra változatra, amely viszont csak a nyugtázási mód szerinti specializációt alkalmaz, hogy az Olvasó errıl is tapasztalatokat szerezzen. 4.3.6 Az érzékelık specializációja csupán a nyugtázási mód szerint A 4.9. ábrán mutatott modell a nyugtázás módját típusszinten (specializációval), az érzékelt változások típusát pedig példányszinten különbözteti meg. Ez a specializáció a nyugtázásTípus nevő attribútumot teszi feleslegessé. Az Érzékelı osztály pedig most amiatt lesz absztrakt, mert benne a getÜzemképes() mővelet absztrakt. Ez a mővelet a leszármazott osztályokban kap megvalósítást. Most az érzékelt változások típusa szerinti specializáció hiánya igényel több figyelmet a programozótól, illetve több mőveletfárordítást futási idıben. Bıvebb információval itt is a pszeudokódú leírás szolgál. 4.9. ábra: Csak a nyugtázás módja szerinti specializáció ABSZTRAKT OSZTÁLY Érzékelı { zóna: Zóna; érzékelıTípus: int; fizikaiAzonosító: int; riasztás(): void { zóna.riasztás(érzékelıTípus) // Ha az érzékelıtípusra is lenne speciali// záció, a paraméterre nem lenne szükség!! } ABSZTRAKT getÜzemképes(): boolean; PRIVÁT kapottAzonosító(): int { // Mint a 4.3.4. szakaszban. }
144
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
// A következı mővelet a 4.9. ábrán nem szerepelt, mert csak a // konstruktorok írása tette nyilvánvalóvá, hogy erre is szükség van. PRIVÁT közösKezdetiBellítás(pZóna: Zóna, pFizikaiAzonosító: int, pÉrzékelıTípus: int) // Ha az érzékelıtípusra is lenne // specializáció, erre nem lenne szükség!!! : void { // Olyan kezdeti beállító utasításokat tartalmaz, amelyek ismétlését // szeretnénk elkerülni a leszármazott osztályok konstruktoraiban. zóna := pZóna; fizikaiAzonosító := pFizikaiAzonosító; érzékelıTípus := pÉrzékelıTípus // Ha az érzékelıtípusra is // lenne specializáció, akkor // erre nem lenne szükség!!! } } OSZTÁLY ÉrzékelıAktívFizikaiNyugtázással SZÜLİJE Érzékelı { utolsóNyugTázás: Time; OSZTÁLYATTRIBÚTUM idıKöz: int:=2; getÜzemképes(): boolean { HA másodperc(most(), utolsóNyugtázás) < idıKöz AKKOR VISSZATÉR true ELSE VISSZATÉR false } PRIVÁT nyugtázóJelFogadás(): void { // Mint a 4.3.4. szakaszban. } // A 4.9.ábrával ellentétben itt megadjuk a konstruktort is. ÉrzékelıAktívFizikaiNyugtázással(pZóna: Zóna, pFizikaiAzonosító: int, pÉrzékelıTípus: int) // Ha az érzékelıtípusra is lenne // specializáció, erre nem lenne szükség!!! { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pÉrzékelıTípus); } } OSZTÁLY ÉrzékelıPasszívFizikaiNyugtázással SZÜLİJE Érzékelı { // A 4.9.ábrával ellentétben itt megadjuk a konstruktort is. getÜzemképes(): boolean { VISSZATÉR nyugtázóVálasz() } PRIVÁT nyugtázóVálasz(): boolean { // Mint a 4.3.4. szakaszban. } // A 4.9.ábrával ellentétben itt megadjuk a konstruktort is. ÉrzékelıPasszívFizikaiNyugtázással(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: int) // Ha az érzékelıtípusra is lenne // specializáció, erre nem lenne szükség!!! { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pÉrzékelıTípus); } }
EGY LAKÁS BIZTONSÁGI RENDSZERE
145
4.3.7 Az érzékelık többszintő hierarchikus specializációja A 4.10. ábra modelljében az érzékelt változás típusa a fı specializációs szempont, a nyugtázás módja pedig ennek alárendelt szempont. A 4.11. ábra modelljében éppen fordítva van. Esetünkben egyik modell sem megfelelı, mert a két szempont független egymástól, tehát egyik sem alárendeltje a másiknak. Mindkét modell hátránya a definíciók redundanciája: A 4.10. ábra modelljében például az aktív nyugtázási módhoz tartozó attribútum- és mőveletdefiníciókat meg kell ismételni a MozgásÉrzékelıAFNy és a NyílásZáróÉrzékelıAFNy osztályok definíciójában is. 4.10. ábra: Többszintő hierarchikus specializáció – Elsıdleges szempont az érzékelt változás típusa
Nem arról van szó, hogy ezen modellváltozatokat mindig kerülni kellene, csupán az egymástól független több szempont szerinti osztályozás esetére nem ajánlhatók. Ha történetesen a mozgásérzékelıknél A és B nyugtázási mód, a nyílászáróérzékelıknél pedig C és D nyugtázási mód volna lehetséges, akkor éppen a 4.10. ábra modelljéhez hasonló hierarchikus specializáció volna a legjobb megoldás.
4.11. ábra: Többszintő hierarchikus specializáció – Elsıdleges szempont a nyugtázás módja
146
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
Ellenırzı/magyarázó kérdések: 1. A 4.10. ábrán a MozgásÉrzékelı osztály miért van absztrakt osztálynak jelölve, ha annak definíciójában nem látható egyetlen absztrakt mővelet sem?
2. A 4.11. ábrán az ÉrzékelıAktívFizikaiNyugtázással osztály definíciójában a getÜzemképes() mővelet már nem absztrakt, akkor az osztály miért az?
Annak ellenére, hogy a MozgásÉrzékelı osztály definíciójában nem látható egyetlen absztrakt mővelet sem, ennek az alosztálynak mégis van absztrakt mővelete: a getÜzemképes() mővelet, amelyet az alosztály az Érzékelı osztálytól örököl. Mert ebben az osztályban a riasztás() mővelet absztrakt (amely itt szintén örökölt mővelet).
4.3.8 Az érzékelık hálós specializációja (csak elvi lehetıség) Az elızı szakaszban szerzett tapasztalatok szerint esetünkben nem hierarchikus, hanem hálós specializációt célszerő alkalmazni. Egy ilyen modellt mutat a 4.12. ábra, amely elsı látásra tökéletes megoldásnak tőnik. Ám – az Olvasónak talán meglepı – a fejlesztıi környezetek (programnyelvek) többsége az ilyen hálós specializációt nem támogatja.
4.12. ábra: Az érzékelık hálós specializációja – A programozási környezetek nem támogatják
EGY LAKÁS BIZTONSÁGI RENDSZERE
147
A modell a következı megfontolásból látszik tökéletesenek: • A modell az érzékelıknek mind a két szempont szerinti (al)osztályozását (specializációját) érvényesíti. • Ez az érzékelıknek a egyik szempont szerinti osztályozását a másik szempont szerinti osztályozástól valóban függetlenül oldja meg. • Miközben az egyik szempont szerinti kategóriák szabadon kombinálhatók a másik szempont szerinti kategóriákkal, semelyik kategóriához tartozó attribútumokat vagy mőveleteket sem kell többszörösen definiálni. Például a mozgásérzékelés képességét csak a MozgásÉrzékelı osztályban, az aktív nyugtázás képességét csak az ÉrzékelıAktívFizikaiNyugtázással osztályban kell definiálni; ezt követıen a MozgásÉrzékelıAFNy osztályban már semmilyen attribútumot, illetve mőveletet sem kell definiálni, mégis ennek példányai egyszerre rendelkeznek mind a mozgásérzékelés képességével, mind az aktív nyugtázás képességével, mert a MozgásÉrzékelıAFNy osztály az egyiket MozgásÉrzékelı osztálytól, a másikat az ÉrzékelıAktívFizikaiNyugtázással osztálytól örökli meg. Azonban annak is megvan az oka, hogy a fejlesztıkörnyezetek többsége a több irányból való (kiterjesztés típusú) öröklés lehetıségét mégis kizárja: Ugyanis ellenkezıleg elıfordulhat, hogy a leszármazott osztály több irányból is örököl azonos nevő attribútumokat vagy mőveleteket, mint ahogy a 4.12. ábrán a MozgásÉrzékelıAFNy osztály duplán – a MozgásÉrzékelı osztály közvetítésével is és az ÉrzékelıAktívFizikaiNyugtázással osztály közvetítésével is – megörökli az Érzékelı osztály attribútumait és mőveleteit. Történetesen a MozgásÉrzékelıAFNy osztály esetében ezt a jelenséget úgy is értelmezhetjük, hogy a MozgásÉrzékelı osztály felıl örökölt zóna attribútum és az ÉrzékelıAktívFizikaiNyugtázással osztály felıl örökölt zóna attribútum egy és ugyanaz. – Gond abban a (miénkétıl különbözı) esetben van, ha az eltérı irányokból örökölt azonos nevő attribútumoknak más a típusa, vagy azonos nevő mőveleteknek nem csak a szignatúrája különbözik, hanem a visszatérési értékének típusa is. – Itt nincs hely annak részletezésére, hogy az ilyen esetek kezelésére javasolt megoldások mindegyike, járhat valamilyen kellemetlen következményekkel; megelégszünk azzal, ha az Olvasó elhiszi, hogy az OO-programnyelvek nagy tudású megalkotóinak megvolt az oka kizárni a hálós specializációt, azaz a több irányból való (kiterjesztés típusú) öröklıdést. Döntésükben feltételezhetıen az a körülmény is szerepet játszott, hogy az öröklıdés más konstrukcióval is helyettesíthetı, ahogy azt a következı szakaszban az Olvasó is meg fogja tapasztalni. 4.3.9 Specializáció kombinálása kompozícióval Ha az érzékelık a rendszer legbutább elemei, akkor miért foglalkoztunk ilyen sokat a statikus modellezésükkel? – Mert az Olvasóval is szeretnénk beláttatni, hogy a 4.13. ábra és a 4.14. ábra szerinti modellek elınyösebbek a többi számításba vehetı megoldásnál. Mindkét megoldás jellemzıje, hogy csak az egyik szempont szerinti specializációt alkalmazza közvetlenül az Érzékelı osztályra, a másik szempont szerinti specializáció tárgya pedig az Érzékelı osztály egy komponense. A 4.13. ábra modellje tekinthetı a 4.8. ábra szerinti modell újragondolásának, a 4.14. ábra modellje ugyanilyen viszonyban áll a 4.9. ábra modelljével.
148
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.13. ábra: Specializáció kombinálása kompozícióval – Komponens a NyugtázásTípus
4.14. ábra: Specializáció kombinálása kompozícióval – Komponens az ÉrzékelıTípus
EGY LAKÁS BIZTONSÁGI RENDSZERE
149
Pszeudokód formájában a 4.13. ábra modelljéhez adunk bıvebb magyarázatot, a 4.14. ábra modelljének megfelelı pszeudokód megírását az Olvasóra bízzuk. // Specializáció kombinálása kompozícióval ABSZTRAKT OSZTÁLY NyugtázásTípus { ABSZTRAKT getÜzemképes(): boolean; PRIVÁT kapottAzonosító(): int { // A rendszermegszakítás vagy rendszerhívás útján kapott // nyugtázó üzenetbıl visszadja az érzékelı azonosítóját. ... } } OSZTÁLY AktívFizikaiNyugtázás SZÜLİJE NyugtázásTípus { utolsóNyugtázás: Time; OSZTÁLYATTRIBUTUM idıKöz: int:=2; getÜzemképes(): boolean { HA másodperc(most(), utolsóNyugtázás) < idıKöz AKKOR VISSZATÉR true ELSE VISSZATÉR false } PRIVÁT nyugtázóJelFogadás(): void { HA kapottAzonosító()=fizikaiAzonosító AKKOR utolsóNyugtázás:=most() } // Konstruktor: AktívFizikaiNyugtázás() {} } OSZTÁLY PasszívFizikaiNyugtázás SZÜLİJE NyugtázásTípus { getÜzemképes(): boolean { VISSZATÉR nyugtázóVálasz() } PRIVÁT nyugtázóVálasz(): void { // A ... helyén egy nem részletezett rendszerhívás. ... HA kapottAzonosító()=fizikaiAzonosító AKKOR VISSZATÉR true KÜLÖNBEN VISSZATÉR false } // Konstruktor: PasszívFizikaiNyugtázás() {} } ABSZTRAKT OSZTÁLY Érzékelı { zóna: Zóna; fizikaiAzonosító: int; nyugtázásTípus: NyugtázásTípus; ABSZTRAKT riasztás(): void; // A getÜzemképes() mővelet csak delegálódik a komponensnek. getÜzemképes(): boolean { VISSZATÉR nyugtázásTípus.getÜzemképes() } PRIVÁT közösKezdetiBellítás(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: int): void { // Olyan kezdeti beállító utasításokat tartalmaz, amelyek ismétlését // szeretnénk elkerülni a leszármazott osztályok konstruktoraiban. zóna := pZóna; fizikaiAzonosító := pFizikaiAzonosító; nyugtázásTípus := pNyugtázásTípus } }
150
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
OSZTÁLY MozgásÉrzékelı SZÜLİJE Érzékelı { riasztás(): void { zóna.riasztásM() } // Konstruktor: MozgásÉrzékelı(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: NyugtázásTípus) { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pNyugtázásTípus); } } OSZTÁLY NyílásZáróÉrzékelı SZÜLİJE Érzékelı { riasztás(): void { zóna.riasztásNy() } // Konstruktor: NyílásZáróÉrzékelı(pZóna: Zóna, pFizikaiAzonosító: int, pNyugtázásTípus: NyugtázásTípus) { közösKezdetiBellítás(pZóna, pFizikaiAzonosító, pNyugtázásTípus); } }
A 4.3.4. szakaszban arra a következtetésre jutottunk, hogy a zóna objektumnak kell lekérdezni az operációs rendszertıl, hogy milyen fizikai érzékelık „lógnak” a neki megfelelı fizikai zónán, és feltételeztük, hogy az operációs rendszer válaszul a létezı fizikai érzékelık egyedi alcsatornakódjainak listáját adja vissza. Ezt követıen a zóna az operációs rendszertıl minden fizikai érzékelıre egyenként lekérdezi • az érzékelt változás típusát, • az üzemképesség nyugtázásának módját, • a nyugtázó üzenetben / válaszban közölt fizikai azonosítót. (A lekérdezés egy – az operációs rendszernek szóló – rendszerhívás, amelynek paramétere az adott fizikai érzékelı alcsatornakódja.) Ha az üzemképesség nyugtázásának módja aktív nyugtázás, akkor (a 4.3.4. szakaszban elkezdett gondolatmenetet folytatva) a zóna az AktívFizikaiNyugtázás() konstruktor megfuttatásával létrehoz egy AktívFizikaiNyugtázás-példányt, és azt (egy újabb rendszerhívással) regisztrálja az operációs rendszernél mint az adott fizikai érzékelıtıl érkezı aktív nyugtázás miatti rendszermegszakítás címzettjét. Ugyancsak a zóna a MozgásÉrzékelı(pZóna, pFizikaiAzonosító, pNyugtázásTípus) konstruktor megfuttatásával létrehoz egy MozgásÉrzékelı-példányt. A paraméterek között pZóna a létrehozó zóna mutatója; pFizikaiAzonosító az operációs rendszer által visszaadott fizikai azonosító, pNyugtázásTípus a megelızıen létrehozott AktívFizikaiNyugtázás-példány mutatója. Végül a zóna a MozgásÉrzékelı-példányt regisztrálja az operációs rendszernél mint az adott fizikai érzékelıtıl érkezı riasztás miatti rendszermegszakítás címzettjét. Ellenırzı/magyarázó kérdések: 1. A 4.13. ábrán a NyugtázásTípus osztály ugyan absztrakt, de nem interfész osztály. Ezzel szemben 4.14. ábrán az ÉrzékelıTípus határozottan interfész osztály. Mibıl adódik a különbség?
A NyugtázásTípus osztálynak nem csak absztrakt mővelete van (lásd a: kapottAzonosító() mőveletet). Az ÉrzékelıTípus osztály viszont csak az egyetlen absztrakt riasztás() mővelettel rendelkezik.
EGY LAKÁS BIZTONSÁGI RENDSZERE 2. A 4.13. ábrán az Érzékelı osztály definíciójában a riasztás() mővelet absztrakt, a getÜzemképes() mővelet pedig konkrét. A 4.14. ábrán éppen fordítva van. Mibıl adódik a különbség?
3. A 4.13. ábrán a MozgásÉrzékelı osztály definíciójában a riasztás() mőveletnek nincs paramétere, a 4.14. ábrán viszont van. Mibıl adódik a különbség?
4. A 4.13. ábra modellje esetében egy érzékelı:Érzékelı objektum honnan tudja, hogy a tartalmazó zónának a riasztásM() és a riasztásNy() üzenetek közül melyiket küldje, illetve hogy a getÜzemképes() kérdésre hogyan válaszoljon?
151
A 4.13. ábra modelljében az Érzékelı osztály riasztás() mővelete csak a MozgásÉrzékelı, illetve a NyílásZáróÉrzékelı alosztályokban kap megvalósítást. A getÜzemképes() mővelet viszont rendelkezik megvalósítással az Érzékelı osztályban: ott az a dolga, hogy a zónától érkezı getÜzemképes() kérdést delegálja a nyugtázásTípus komponensnek. A 4.14. ábra modelljében az Érzékelı osztály riasztás() mővelete rendelkezik megvalósítással: ott az a dolga, hogy a fizikai érzékelı által kiváltott rendszermegszakítást delegálja az érzékelıTípus komponensnek. A getÜzemképes() mővelet viszont csak az ÉrzékelıAktívFizikaiNyugtázással, illetve a ÉrzékelıPasszívFizikaiNyugtázással alosztályokban kap megvalósítást. A 4.13. ábrán a MozgásÉrzékelı osztály az Érzékelı osztály leszármazottja, tehát az utóbbitól megörökli a zóna példányattribútumot, tehát azt nem kell átadni paraméterként a MozgásÉrzékelı-példánynak. A 4.14. ábrán a MozgásÉrzékelı osztály nem leszármazottja az Érzékelı osztálynak, tehát nem rendelkezik zóna attribútummal, tehát annak bármely mővelete csak akkor láthatja a zóna objektumot, ha annak mutatóját megkapja egy paraméterben. Mivel az Érzékelı osztálynak nem lehet közvetlen példánya, ezért az érzékelı objektum közelebbrıl vagy a MozgásÉrzékelı osztálynak, vagy a NyílásZáróÉrzékelı osztálynak a példánya: az elıbbi esetben a riasztásM(), az utóbbi esetben pedig a riasztásNy() üzenetet fogja küldeni. Az érzékelı objektum a getÜzemképes() kérdést a nyugtázásTípus nevő komponensének delegálja, tehát arra érdemben ez a komponens fog válaszolni. E komponensnek a NyugtázásTípus csak statikus típusa, mivel ennek az osztálynak nem lehet közvetlen példánya. Tehát a nyugtázásTípus objektum végeredményben vagy az AktívFizikaiNyugtázás,
152
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
5. A 4.14. ábra modellje esetében egy érzékelı:Érzékelı objektum honnan tudja, hogy a tartalmazó zónának a riasztásM() és a riasztásNy() üzenetek közül melyiket küldje, illetve hogy a getÜzemképes() kérdésre hogyan válaszoljon? 6. Miután a zóna objektum létrehozta a kapcsolódó érzékelı objektumokat, késıbb is számon kell-e tartania, hogy az egyes érzékelı objektumok az érzékelt változás típusa, illetve a nyugtázás módja szerint milyen típusúak? 7. A 4.14. ábra modelljében a MozgásÉrzékelı, illetve a NyílásZáróÉrzékelı osztály riasztás(zóna) mőveletében miért van szükség a zóna paraméterre?
vagy a PasszívFizikaiNyugtázás alosztályok példánya, és ebbıl adódóan a getÜzemképes() kérdésre az ezen alosztályok egyikében adott módon fog válaszolni Erre az Olvasó önállóan válaszol.
Nem kell. – A 4-5. kérdések kapcsán tett megfontolásokból kiderül, hogy elegendı, ha az érzékelı objektum tudja magáról, hogy milyen típusú.
A MozgásÉrzékelı osztály riasztás( zóna) mővelete megvalósításának zóna.riasztásM() formában üzenetet kell küldeni a megfelelı zónának; hasonlóan a NyílásZáróÉrzékelı osztály riasztás(zóna) mővelete megvalósításában is kell lenni egy zóna.riasztásNy() akciónak. A 4.14. ábra modelljében az említett osztályok az Érzékelı osztálynak nem leszármazottai, hanem komponensei (alkatrészei), így ık nem örökölhetik meg az Érzékelı osztály zóna attribútumát, így a példányaik csak akkor képesek üzenetet küldeni a megfelelı zóna objektumnak, ha elıtte egy paraméterben megkapják annak mutatóját
4.3.10 A statikus modell (az áttekintı osztálydiagram) második változata A 4.15. ábrán a Zóna osztály specifikációjának a 4.6. ábráról idemásolt változata látható.Az elızı szakaszban elıadottak – különösen a 4-6. kérdésekkel megvilágított tények – alapján ez a specifikáció alapos átdolgozásra szorul, és akkor a 4.5. ábrán mutatott áttekintı osztálydiagram sem maradhat változatlan. Az elızı szakasz 6. kérdésére adott válaszban már megfogalmaztuk, hogy a zóna objektumnak felesleges számon tartani, hogy a rákapcsolt érzékelı objektumok milyen típusúak. Tehát a 4.15. ábra szerinti négy attribútumspecifikáció helyett csak a következı kettıre van szükség: - érzékelıSzám: int - érzékelı[érzékelıSzám]: Érzékelı.
EGY LAKÁS BIZTONSÁGI RENDSZERE
153
4.15. ábra: A Zóna osztály módosításra szoruló definíciója
Persze a dinamikus modellezés (4.4. alfejezet) még további attribútumok szükségességére is fényt fog deríteni; vagy ha visszalapozunk a 4.3.3. szakaszban adott pszeudokódú leírásokhoz, már azok utalnak rá, hogy a Zóna szerkezetében be kell vezetni a következı két példányattribútumot. - távozássalÉlesítve: boolean = false - otthonTartÉlesítve: boolean = false. Az érzékelt változás típusa szerinti specializációt alkalmazó eddigi modellek pedig azt mutatták, hogy a Zóna osztálynak rendelkezni a kell a következı példánymőveletekkel is: + riasztásM(): void + riasztásNy(): void Az elızı szakaszban mondottak fényében a Zóna konstruktorának + Zóna(pMÉrzékelıSzám: int, pNyÉrzékelıSzám: int) alakú specifikációja is tarthatatlanná válik. Nem csak azért,mert nincs szükség kétféle érzékelıszámra, hanem azért is, mert a vezérlés objektum semmilyen érzékelıszámot sem tud átadni paraméterként a Zóna konstruktorának, hiszen abban állapodtunk meg (még a 4.3.4. szakaszban), hogy a vezérlés objektum csak annak a fizikai zónának a csatornakódját kérdezi le az operációs rendszertıl, amelyhez a zóna szoftverobjektumot létre kell hozni, és azt már a (létezı) zóna objektum dolga kideríteni, hogy hány fizikai érzékelı lóg az általa képviselt fizikai zónán. Tehát ha valamit mégis át kell venni paraméterként a Zóna konstruktorának az a megfelelı fizikai zóna csatornakódja, minek következtében a konstruktor új specifikációja: + Zóna(pCsatornaKód: int). Hasonló okból egyszerősödik a Vezérlés osztály konstruktora is: A környezet nem tudja paraméterként átadni a Vezérlés (4.6. ábra szerinti) konstruktorának a pKTáblaSzám és pZónaSzám paramétereket, mert a már létezı Vezérlés-példánynak lesz a dolga „letapogatni”, hogy hány (fizikai) kapcsolótábla és fizikai zóna létezik a rendszerben. Rendszerünknek az idáig történt megfontolásokkal kapott áttekintı osztálydiagramját a 4.16. ábra mutatja. Ez a diagramram az érzékelıkre vonatkozóan a 4.13. ábra modelljét vette át. Ellenırzı/magyarázó kérdések (minden kérdés a 4.16. ábrára vonatkozik): 1. Mit jelent az 1..zónaSzám vagy az Ugyanazt mint az 1..* számosság, csak a * 1..érzékelıSzám alakú számosság? helyett például az érzékelıSzám valamivel konkrétabban utal arra, hogy egy adott zónánál az érzékelık száma egy adott szám.
154
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.16. ábra: A rendszer áttekintı osztálydiagramjának második változata
EGY LAKÁS BIZTONSÁGI RENDSZERE 2. Mibıl látszik, hogy a már létezı Vezérlés-példánynak lesz a dolga „letapogatni”, hogy hány fizikai kapcsolótábla és fizikai zóna létezik a rendszerben? 3. Mibıl látszik, hogy ez a modell az érzékelıkre vonatkozóan a 4.13. ábra modelljét vette át?
4. A Vezérlés osztály defíníciójával a 4.6. ábra óta közvetlenül nem foglalkoztunk. Ezen osztály definíciójában az említett ábrához képest mégis látható egy változás: új elemként megjelent benne a riasztás() mővelet. Ez mivel magyarázható?
155
Abból, hogy a Vezérlés() konstruktornak nincs paramétere, azaz a környezet anélkül hozza létre a Vezérlés-példányt, hogy értéket adna a kTáblaSzám és a zónaSzám attribútumoknak. Mert ahhoz hasonlóan az érzékelt változás típusa szerinti specializációt közvetlenül az Érzékelı osztályra alkalmazza, a másik szempont szerinti specializáció tárgya pedig az Érzékelı osztály NyugtázásTípus komponense. A Vezérlés osztálynak ez a példánymővelete kezeli a Vezérlés-példányhoz valamely zóna objektumtól érkezı riasztás üzenetet. Ennek szükségessége már a 4.3.3. szakaszban kiderült, mert a Zóna osztály riasztás(érzékelıTípus), riasztásM(), illetve riasztásNy() mőveleteinek ottani pszeudokódjában jelent meg elıször a vezérlés.riasztás() akció, amely szerint a zóna a vezérlés objektumnak küld egy riasztás() üzenetet.
A 4.16. ábra a statikus modellnek még nem a végleges változatát mutatja, hiszen a dinamikus modellezés még hátra van, azonfelül idáig a feladatleírásban (4.1 alfejezet) adott követelmények közül is több felett nagyvonalúan elsiklottunk.
156
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.4 A probléma dinamikus modellje A megelızı esettanulmányokban már megszokhattuk, hogy a rendszer mőködését alapvetıen az annak „agyát” képezı vezérlés objektum határozza meg, és így ennek az objektumnak az állapotdiagramjából lehet a legtöbbet megtudni a vezérelt rendszer viselkedérıl is. Az itt tárgyalt probléma esetében némileg mást tapasztalunk: Mivel a zónák egymástól függetlenül élesíthetık, így inkább a zóna objektumokon múlik, hogy hogyan kezeli a rendszer az érzékelık jelzéseit. A zóna állapotdiagramja valóban érdekesebb, mint a vezérlés objektumé. Az utóbbi szerepe (miután létrehozta a rendszer komponenseit) a rendkívüli eseteket kivéve csak arra korlátozódik, hogy információkat közvetít a kapcsolótáblák és a zónák között. – Az azonban csak látszat, hogy itt a rendszer „agya” kevesebbet vállalna magára, mert valójában a zóna objektumok is az „agy” részei, Tehát esetünkben a rendszer „agya” a vezérlés objektumból és a –csak logikailag elkülönülı – zóna objektumokból áll. 4.4.1 A Zóna osztály állapotdiagramjának elsı változata A 4.17. ábra állapotdiagramjához lényegi részben a 4.1. alfejezetben adott feladatleíráson alapuló megfontolások vezettek.
4.17. ábra: A Zóna állapotdiagramjának elsı változata
Ezen állapotdiagram megrajzolójának a következı tényekre kellett gondolnia: • Meg kell különböztetni egy alapállapotot (az ábrán: Alap) és az élesített állapotot, hiszen a zóna csak élesített állapotban reagál az érzékelık riasztás jelzésére. • Mivel a zóna csak távozással élesítést követıen veszi figyelembe a mozgásérzékelı(k)tıl érkezı riasztást, az élesített állapot megkülönböztetése kevésnek tőnik,
EGY LAKÁS BIZTONSÁGI RENDSZERE
157
célszerőbbnek látszik egy Otthon tartózkodással élesítve és egy Távozással élesítve állapot bevezetése. •
Mivel egy – az adott zónára vonatkozó – kiiktatás parancsot követı élesítés parancs nem élesítheti a zónát, az alapállapottól meg kell különböztetni egy kiiktatott állapotot is (az ábrán: Kiiktatva), amelyben az élesítés parancs ellenére a zóna nem lesz élesítve.
A diagramon jelzett események, másképpen üzenetek, amelyek vagy a vezérlés objektumtól (pl. kiiktatás, élesítésOtthon, élesítésTávozással, hatástalanítás), vagy az érzékelıktıl érkezhetnek (pl: riasztásM a mozgásérzékelıktıl, riasztásNy a nyílászáróérzékelıktıl), vagy az operációs renszertıl (pl. órajel). A legutóbbi egy – azonos idıközönként jelentkezı – rendszermegszakítás, a zóna ennek jelentkezésekor kérdezi le az összes érzékelıjétıl, hogy az (még mindig) üzemképes-e. Némi magyarázatot igényel a [nincs válasz] ırszem, mivel ez nem egy szimpla feltételvizsgálat, hanem azt a folyamatot takarja, amelyben a zóna minden érzékelıjéhez sorban egy getÜzemképes() kérdést intéz, és a [nincs válasz] feltétel akkor teljesül, ha legalább egy érzékelı objektumnál a getÜzemképes() kérdés visszatérési értéke false lesz. Ellenırzı/magyarázó kérdések (minden kérdés a 4.17. ábrára vonatkozik): 1. Nem lenne jobb, ha a kiiktatott zónák Két okból is határozottan nem: eleve meg sem kapnák az élesítés üzene1. Ez idıben semmilyen megtakarítást nem teket? jelentene, éppen ellenkezıleg: szaporítaná a kommunikációt a vezérlés és a zóna objektumok között. Ugyanis az OO felfogás szerint a zóna kiiktatott állapota a zóna jellemzıje, tehát azt a zóna valamely attribútumának kell mutatnia. Tehát ahhoz, hogy a vezérlés eldönthesse, mely zónáknak küldje el az élesítés üzenetet, minden zónától le kellene kérdeznie, hogy az kiiktatott állapotban van-e vagy sem. 2. Nem arról van szó, hogy a zóna objektumnak kiiktatott állapotban nem kell reagálnia az élesítés eseményre, hanem arról, hogy másképpen kell, mint az alapállapotban: a kiiktatott állapotól az élesítés esemény alapállapotba viszi vissza a zónát. 2. Az élesítés esemény a kiiktatott állapotól Ez az átmenet azt a célt szolgálja, hogy egy késıbbi élesítés már ne Kiiktatva állapotmiért viszi vissza alapállapotba a zónát? ban érje a zónát, vagyis egy kiiktatás esemény mindig csak a következı élesítés hatása alól iktassa ki azt. 3. Ha egy érzékelı üzemképtelen, akkor A kérdés azért rossz, mert nem tesz különbséget a fizikai érzékelı és az azt képvielı hogyan képes válaszolni a getÜzemkéérzékelı szoftverobjektum között. – A pes() kérdésre? (Lásd a [nincs vágetÜzemképes() kérdésre az utóbbi válalasz] ırszem megvalósítását.) szol, üzemképtelenné pedig az elıbbi válhat.
158
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4. A vezérlés.riasztás() akcióspecifikációból kiolvasható, hogy a vezérlés objektum az üzenet címzettje. Az eseményüzenetek (pl. kiiktatás, élesítésOtthon) specifikációjából viszont nem látszik, hogy melyik objektumtól érkezett. – Honnan tudja a zóna, hogy melyik másik objektum az üzenet küldıje. 5. Az elızı kérdés folytatása: Mi a megoldás akkor, ha az üzenet címzettjének valamilyen célból mégis ismerni kell a „feladót”? 6. Nem hiba, hogy a Zóna állapotdiagramja figyelmen kívül hagyja, hogy az érzékelıknél az üzemképesség nyugtázásának kétféle módja létezik?
7. Az érzékelı objektumok korábbi szakaszokban adott konstrukcióját is számításba véve legalább mennyi idınek kell eltelnie két órajel esemény között?
8. Milyen szuperállapot bevezetésével lehetne egyszerősíteni az állapotdiagramot?
Nem kell tudnia, mert (ebben az alkalmazásban) sehol nem kell felhasználnia, hogy ki az üzenet küldıje.
A „feladó” az üzenet egyik paraméterében közölheti a saját mutatóját.
Nem hiba. A fizikai érzékelıknek ezt a sajátosságát az érzékelı objektum teljesen eltakarja a zóna elıl. – Lásd a 4.3.4. szakaszban a getÜzemképes() mővelet (táblázatban adott) leírásához főzött 1. megjegyzést! Legalább 2 másodpercnek. Ennél gyakrabban nem érdemes lekérdezni az (aktív nyugtázó) érzékelı üzemképességét. – Lásd a 4.3.4. szakaszban az idıKöz attribútum (táblázatban adott) leírását, valamint a 4.16. ábrán az AktívFizikaiNyugtázás osztály definíciójában az idıKöz: int = 2 attribútumspecifikációt! Lásd az Élesítve szuperállapotot a 4.19. ábrán!
4.4.2 A Zóna osztály állapotdiagramjának második változata Az elızı szakaszban készült állapotdiagrammal kapcsolatban is fel kell tenni a szokásos kérdést: Rendelkezik-e a Zóna osztály olyan példányattribútumokkal, amelyekkel a zóna objektum állapotai megkülönböztethetık? Ha nem, akkor pótolni kell. A Zóna osztály 4.16. ábrán látható definíciójában látható távozássalÉlesítve: boolean = false otthonTartÉlesítve: boolean = false attribútumok képesek megkülönböztetni az alapállapotot (amelyben mindkettı értéke false) és a kétféle élesített állapotot. Elıször a 4.3.3. szakaszban használtuk ezeket az attribútumokat a Zóna osztály riasztásM(), illetve riasztásNy() mőveleteinek pszeudokódjában: riasztásM(): void { HA távozássalÉlesítve AKKOR vezérlés.riasztás() } riasztásNy(): void { HA távozássalÉlesítve VAGY otthonTartÉlesítve AKKOR vezérlés.riasztás() }
EGY LAKÁS BIZTONSÁGI RENDSZERE
159
Az utóbbi mővelet kódját nézve a megoldás utólag nem tőnik a legjobbnak. Szerencsésebbnek látszik a két boolean típusú attribútumot egyetlen élesítve: int = 0 attribútumra cserélni, amelynek 0 értéke az Alap állapotot, 1 értéke az Otthon tartózkodással élesítve állapotot, 2 értéke a Távozással élesítve állapotot jelenti. Ezzel a riasztásM(), illetve riasztásNy() mőveletek pszeudokódja így egyszerősödik: riasztásM(): void { HA élesítve=2 AKKOR vezérlés.riasztás() } riasztásNy(): void { HA élesítve>0 AKKOR vezérlés.riasztás() }
Már csak a kiiktatott állapot megkülönböztetésére kell bevezetni egy kiiktatva: boolean = false példányattribútumot. Ezzel együtt az Alap állapotot az élesítve=0 és a kiiktatva= false értékek jelzik. A fenti meggondolások alapján a Zóna osztály specifikációja a 4.18. ábra szerint alakul át.
4.18. ábra: A Zóna osztály immár harmadik változata
A 4.19. ábra a Zóna egy olyan állapotdiagramját mutatja, amelyen az Otthon tartózkodással élesítve és a Távozással élesítve állapotokat már egy Élesítve szuperállapotba foglaltuk. Ennek következtében a diagram tömörebb lett, mert • a hatástalanítás eseménnyel kiváltott átmenetet, • a riasztásNy eseményt kezelı akciót és • az órajel eseményt kezelı akciót itt csak egyszer kellett alkalmazni. Ha már úgyis készült egy új változat az állapotdiagramból, annak állapotdobozaiban feltüntettük az állapotjelzı attribútumok értékét kezelı entry akciókat is. (A gyakorlatban – ha a diagramból csak egy változat készül – ez nem jellemzı, mert az ilyen állapotattribútumok többségének szükségessége csak az állapotdiagram megrajzolása után derül ki. Itt azonban azt akartuk, hogy az Olvasó is lássa, hogyan változik az egyes állapotattribútumok értéke az egyes átmenetek hatására.)
160
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.19. ábra: A Zóna állapotdiagramjának második változata
Ellenırzı/magyarázó kérdések (minden kérdés a 4.19. ábrára vonatkozik): 1. A Kiiktatva állapotban az entry/ Az felesleges lenne, mert a zóna a Kiikkiiktatva:=true akció mellett miért tatva állapotból mindig az Alap állapotba nincs egy exit/kiiktatva:=false tér vissza, ahol az entry/kiiktatva:= akció is? false akció gondoskodik az állapotattribútum megfelelı értékérıl. 2. Mi a hatása annak a megoldásnak, hogy Ennek következtében a megadott akció az a riasztásNy/vezérlés.riasztás() Élesítve állapot mindkét alállapotában végrehajtódik. akciót az Élesítve szuperállapot dobozában helyeztük el? HA élesítve > 0 AKKOR … 3. A legegyszerőbben milyen feltétel vizsgálatával állapítható meg, hogy a zóna az Élesítve állapotban van-e? 4.4.3 A Zóna osztály állapotdiagramjának harmadik változata A tervezı idáig csak a probléma lényegi részére koncentrált, arra, hogy a rendszer adjon riasztás jelzést, ha betırés történik. Közben a 4.1. alfejezetben megfogalmazott több követelményrıl megfeledkezett. Vegyük sorra ezeket!: • Az egyébként üzemkész rendszer mőködésének folytatását valamilyen veszély fenyegeti (pl. az akkumulátor töltési szintje lecsökkent). Ezt pl. a Rendszer led sárga villogása (és esetleg egy elviselhetı gyakoriságú, pittyegı hang) jelezheti.
EGY LAKÁS BIZTONSÁGI RENDSZERE
161
•
Adott zónában valamilyen mozgás észlelhetı, vagy valamely nyílászáró nyitva van (függetlenül attól, hogy a rendszer élesítve van-e). Ezt pl. azzal jelezhetı, hogy a zónához tartozó led pirosan világít.
•
Adott zónában valamely érzékelı üzemképtelenné vált. Jelzése: a Rendszer led sárgán, a zónához tartozó led pedig pirosan villog. – De ha a zóna élesítve van, akkor természetesen bekapcsol a riasztás is (megszólal a sziréna, értesítés megy a biztonsági szolgáltató céghez). … van még egy, a digitális óráéhoz hasonló szöveges kijelzı is, amely a felhasználónak szóló további üzenetekre ad lehetıséget.
•
Mivel ez egy esettanulmány, nem pedig egy tényleges projekt, így ezután sem fogunk minden követelmény teljesítésérıl gondoskodni (az akkumulátor töltési szintjének lecsökkenését figyelni különben sem a zónák feladata). – Ez az esettanulmány akkor is eléri célját, ha a modellt a fenti felsorolásnak csupán a második és a harmadik tagjában foglalt követelmények teljesítésének irányában egészítjük ki.
4.20. ábra: A Zóna állapotdiagramjának harmadik változata
162
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
A 4.20. ábra szerinti állapotdiagram a pótlólag figyelembe vett követelmények alapján készült. Szerkesztésében az alábbi megfontolások játszottak szerepet: •
•
Az kevés, hogy az élesített zóna valamilyen változás esetén vezérlés.riasztás() üzenetet ad ki. Az kell, hogy a nem élesített zóna is jelezze (persze a riasztástól különbözı üzenettel) az általa észlelt változást a vezérlés objektumnak, különben az utóbbi nem képes felkérni a kapcsolótáblákat arra, hogy a kijelzıjükön mutassák meg (a zónához tartozó piros led bekapcsolásával), mely zónákban van valamilyen mozgás, változás. Legyen ez a jelzés az észleltVáltozás(pZóna: Zóna) üzenet, amelynek pZóna paraméterében az üzenetet küldı zóna a saját mutatóját adja át (valahogy így: vezérlés.észleltVáltozás(this)), hogy a vezérlés tudja, melyik zónához tartozó led bekapcsolását kérje a kapcsolótáblától. Ha következetesek vagyunk akkor a riasztás jelzésekor is jó lenne, ha a kapcsolótáblán látható lenne, melyik zónától jött a riasztást. Tehát vezérlés.riasztás() akció helyett is jobb lenne egy vezérlés.riasztás(this) akció, azaz a Vezérlés osztály definíciójába a riasztás() mővelet helyett egy riasztás( pZóna: Zóna) mőveletet célszerőbb felvenni.
•
A zóna valamely érzékelı üzemképtelenné válását nem csak élesített állapotban köteles jelezni, mert az üzemképtelenség tényét (a Rendszer leden és a zónához tartozó leden) bármely állapotban meg kell mutatni. Emiatt a Zóna állapotdiagramját nem csak át kell rajzolni, de azon egy új akciónak is meg kell jelenni: vezérlés.üzemképtelenÉrzékelı(this). Tehát a Vezérlés osztály definíciójába egy üzemképtelenÉrzékelı(pZóna: Zóna) mőveletet is fel kell venni.
•
Meg kell különböztetni az észlelt változás miatti riasztás és az üzemképtelenné vált érzékelı miatti riasztás üzeneteket, mert az utóbbinál a sárga Rendszer lednek is világítani kell a kapcsolótáblá(ko)n. Emiatt a Zóna állapotdiagramján a vezérlés.riasztás(this) akció mellett szükség lesz vezérlés.riasztásÜk( this) akcióra is, a Vezérlés osztály definíciójában pedig egy riasztásÜk( pZóna: Zóna) mőveletre is fel. A fentebb mondottak ugyan a megvalósítás részleteiben érintik a Zóna osztály mőveleteit, de a specifikáció szintjén csak a Vezérlés osztálynál jelennek meg új elemek. A Vezérlés osztály 4.21. ábra szerinti specifikációjában az elsı négy mővelet a zónáktól érkezı üzenetekre reagál, az utolsó négy pedig a kapcsolótáblától érkezı parancsokra (azokat delegálja a zónákhoz).
4.21. ábra: A Vezérlés osztály harmadik változata
EGY LAKÁS BIZTONSÁGI RENDSZERE
163
Konkurens események kezelése – Egy kis kitérı A feladatleírásnál (4.1. alfejezet) megállapítottuk, hogy az itt tervezett alkalmazás szó szerinti értelemben nem többfelhasználós rendszer, azonban abban mégi hasonlít hozzá, hogy a vezérlésnek konkurens zónaeseményeket kell feldolgoznia. Például egyszerre több zóna is küldhet észleltVáltozás(pZóna) üzenetet a vezérlés objektumnak. Legalábbis elvben, merthogy a fizikai zónák tényleg képesek párhuzamos mőködésre, de mi a zóna szoftverobjektumokat tervezzük.. – Itt két kérdes merül fel: (1) Egy alkalmazáson belüli szoftverobjektumok esetében hogyan oldható meg a párhuzamos mőködés? (2) Ha az elıbbi kérdésre van pozitív válasz, akkor mit kezd a vezérlés az egyidejőleg több objektumtól érkezı eseményekkel. Az (1)-(2) problémákra a fejlesztıkörnyezet szintjéhez kötıdı kész megoldások léteznek, amelyekrıl a következı fejezet 5.1.2. szakaszában egy picit bıvebben is szó lesz. E megoldások birtokában a konkurencia kezelésének problémájával a tervezınek nem kell részletekbe menıen foglalkozni; elég, ha csak utal annak felmerülésére, és akkor a programozó rutinszerően alkalmazza a szükséges elıre gyártott elemeket. Ellenırzı/magyarázó kérdések: 1. A 4.20. ábrán mi tette szükségessé a Nincs élesítve szuperállapot szerepeltetését?
2. A legegyszerőbben milyen feltétel vizsgálatával állapítható meg, hogy a zóna az Nincs élesítve állapotban van-e? 3. Milyen feltétel vizsgálatával állapítható meg, hogy a zóna az Alap állapotban van-e? 4. Ha a 4.20. ábra szerint a zóna objektum az Élesítve és a Nincs élesítve állapotban is reagál az órajel eseményre, akkor nem lenne jobb, ha az összes többi állapotot magába foglaló Zóna szuperállapotban specifikálnánk az órajel eseményre reagáló akciót? 5. Mit jelent a this paraméter az üzemképteleÉrzékelı(this) üzenetben?
6 A Vezérlés osztály paraméterezett mőveletei között a kiiktatás(…) mőveletnek kivételesen nem egy Zóna típusú pZóna paramétere van, hanem egy int típusú zónaIndex. Mi az oka ennek a
Különben azt a három akciót, amelyet a Nincs élesítve szuperállapot dobozában adtunk meg kétszer kellett volna felvenni: egyszer az Alap dobozban és egyszer a Kiiktatva dobozban. HA élesítve = 0 AKKOR …
HA élesítve = 0 ÉS kiiktatva= false AKKOR … Nem lenne. Ugyanis a két állapotban nem ugyanazzal az akcióval kell válaszolni az órajel eseményre.
Nem. Nem az üzemképtelen érzékelı mutatója. – Annak a zóna objektumnak a mutatója, amelyrıl az állapotdiagram szól, és amely ugyanaz a zóna, amelyhez az üzemképtelenné vált érzékelı tartozik. Ez a mővelet valamelyik kapcsolóTábla objektumtól érkezı kiiktatás parancsra reagál, tehát a paramétert is a kapcsolóTábla objektum adja át. Ez az objektum nem látja a zóna objektumokat, tehát Zóna
164
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
kivételnek?
típusú paramétert sem tud átadni; egyszerően csak azt a (zóna)sorszámot adja át a vezérlés objektumnak, amelyet a lakó a kiiktatás parancs részeként bebillentyőzött. A Vezérlés osztály élesítésOtthon() 7. Mi a különbség a Vezérlés osztály mővelete valamely kapcsolótáblától érkezı élesítésOtthon() mővelete és a parancsra reagál, azt delegálja a zónákhoz. Zóna osztály ugyanilyen nevő mővelete között? A Zóna osztály ugyanilyen nevő mővelete a Vezérlés-példánytól kapott üzenetre reagál, és mindössze a saját állapotát változtatja meg. Ez az állapotváltozása attól függ, hogy az üzenet érkezésekor éppen milyen állapotban van. 8. A Vezérlés osztály kiiktatás(…) A Vezérlés-példányhoz több Zónapéldány kapcsolódik, ezért a neki szóló mőveletének van paramétere, míg a Zóna kiiktatás(…) üzenetben kell lenni egy osztály ugyanilyen nevő mőveletének nincs. Mi az oka ennek a különbségnek? olyan paraméternek, amely közli, hogy a kiiktatás parancs aktuálisan melyik zónára vonatkozik. A Zóna osztály ugyanilyen nevő példánymővelete eleve egy konkrét Zóna-példánynak szól (például ilyen formában: zóna[zónaIndex].kiiktatás()), tehát nincs szükség arra, hogy mővelet paraméterében is megismétlıdjék a zónahivatkozás. 9. Mi történik, ha a zóna objektum Ott- A 4.20. ábra állapotdiagramja szerint a hon tartózkodással élesítve álla- zóna ugyanúgy vezérlés.riasztásÜk( potában valamelyik mozgásérzékelı üzem- this) akciót hajt végre, mintha egy nyílászáróérzékelı hibásodna meg. képtelenné válik? 4.4.4 A Vezérlés osztály állapotdiagramja A korábbi szakaszokban elegendı tudás győlt össze ahhoz, hogy immár a Vezérlés állapotdiagramját is megrajzoljuk. A jelen alfejezet elején sejtettük, hogy a Vezérlés állapotdiagramjának egyszerőbbnek kell lenni, mint a Zóna állapotdiagramjának. A 4.22. ábra szerint nem tévedtünk. Ellenırzı/magyarázó kérdések: 1. Mit csinál a rendszer, ha élesített (az ábrán: Élesítve) állapotában valaki megpróbálja ismételten (hatástalanítás nélkül) élesíteni?
Az ábra szerint semmit, mert a vezérlés az Élesítve állapotban a kapcsolótábláktól érkezı üzenetek közül csak a hatástalanítás üzenetre reagál.
2. A Zóna 4.20. ábra szerinti állapotdiagramjával összevetés után milyen hiányosság állapítható meg a Vezérlés 4.22.
A vezérlés objektum Élesítve állapotában nem mindegyik zóna van Élesítve állapotban. A 4.20. ábra szerint egy ilyen
EGY LAKÁS BIZTONSÁGI RENDSZERE ábra szerinti állapotdiagramján?
3. Hogyan javítható ez a hiányosság?
165
zónától vezérlés objektum az Élesítve állapotában is kaphat észleltVáltozás( pZóna) üzenetet vagy üzemképtelenÉrzékelı(pZóna) üzenetet, azonban ezeket a vezérlés objektum nem kezeli le. A követelmények szerint az említett üzenetekben jelzett eseményeket a kapcsolótáblá(ko)n a zónának (lásd pZóna) megfelelı lednek is mutatania kellene. Lásd a 4.23. ábrát!
4.22. ábra: A Vezérlés állapotdiagramjának elsı változata
A 4.23. ábrán nem csak a 4.22. ábra hibáját javítottuk ki, hanem annak az élesítve állapotattribútumnak az értékváltozásait is feltüntettük, amelynek szükségességére éppen a 4.22. ábra alapján következtethettünk. 4. Az Vezérlés osztály élesítve példányattribútuma miért nem int típusú, mint a Zóna osztály ugyanilyen nevő attribútuma? 5. Nem hiba, hogy a 4.23. ábrán nem látszik, hogy a riasztás(pZóna), illetve a riasztásÜk(pZóna) üzenetek esetén is fel kellene kérni a kapcsolótáblát, hogy jelezze, melyik zóna a riasztás forrása?
Mert a vezérlés szintjén nem szükséges nyilvántartani, hogy a rendszer legutoljára otthon tartózkodással vagy távozással lett-e élesítve. Az ábrán valóban nem látszanak ezek a kapcsolótáblának szóló kérések, de ez nem jelenti azt, hogy a modellbıl is hiányoznának. Mint az a korábban (például a zsebszámológép probléma tárgyalásánaál a 3.4.1. szakaszban) már láttuk hogy a riasztás(pZóna) / alakú akcióspecifikáció a riasztás(pZóna) / riasztás(pZóna) alak rövidítése. – Az utóbbiban a / elıtt a zónától érkezı üzenet áll, utána pedig a vezér-
166
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK lésnek erre az üzenetre reagáló mővelete. A kapcsolótáblának szóló kérés a vezérlés riasztás(pZóna) mőveletének a megvalósításában van elrejtve.
4.23. ábra: A Vezérlés állapotdiagramjának második változata
4.4.5 Szekvenciadiagram egy kiiktatott zóna kezelésérıl A szekvenciadiagramok egyik alkalmazása, hogy velük addig modellezzük egy rendszer alkotóelemiként szóba jöhetı objektumok együttmőködésének kiragadott konkrét eseteit, mígnem egyszer már elegendı tudással rendelkezünk a történések típusszintő leírására is például állapotdiagrammal vagy tevékenységdiagrammal. Egy másik alkamazásuk a modellezés ellenkezı sorrendben történı végrehajtásához kapcsolható, vagyis amikor elıbb állapotdiagramok készülnek a történéseket. Bár egy adott típusú objektum állapotdiagramja tele lehet más objektumoktól érkezı üzenetekkel, más objektumok állapotára rákérdezı ırszemekkel vagy más objektumoknak üzenetet küldı akciókkal, ez a diagram mégiscsak egyfajta objektum nézıpontjából ábrázolja a történéseket. Tehát az állapotmodellek ellenırzésére jól jöhetnek a többféle objektum együttmőködését modellezı, és így másfajta nézıpontot érvényesítı szekvenciadiagramok. Például a 4.22. ábra modellje hibájának felfedezésére egy szekvenciadiagram is módot adott volna, ha az a rendszer komponenseinek egy olyan folyamatban való együttmőködését ábrázolja, amely a rendszer alapállapotában kezdıdik, egy zóna kiiktatásával folytatódik, melyet a rendszer távozással élesítése követ, ezután ad riasztást a kiiktatott zóna egyik érzékelıje, amelyet a zóna egy észleltVáltozás(this) üzenetben továbbít a vezérlés objektumnak. – A 4.24. ábra szekvenciadiagramja éppen ezt az együttmőködést ábrázolja. (A szekvenciadiagram a zsúfoltság elkerülése érdekében csupán három zóna objektumot tartalmaz mutatóban.) A 4.22. ábra modelljének hibájára a bekeretezett lépéseknél jöhet rá a szemlélı.
EGY LAKÁS BIZTONSÁGI RENDSZERE
167
4.24. ábra: Szekvenciadiagram egy kiiktatott zóna kezelésérıl
Ellenırzı/magyarázó kérdések (a kérdések a 4.24. ábrára vonatkoznak): 1. A szekvenciadiagram alapján hogyan ve- A 4.24. ábrán a bekeretezett lépésekbıl a hetı észre a 4.22. ábra modelljének hibája? zóna[1] produkálja az észleltVáltozás(zóna[1]) üzenetet, azonban a 4.22. ábra állapotdiagramja a vezérlés Élesítve állapotában nem tartalmaz erre az üzenetre reagáló akciót.
168
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
2. Hogyan lehetséges, hogy a szekvenciadiagramon az élesítve attribútum hol boolean típusú értéket kap (pl. élesítve :=true), hol meg szám típusú értéket (pl. élesítve:=1)
3. A rendszer élesítésOtthon üzenettel (paranccsal) lett élesítve, tehát a érzékelık riasztásNy() üzenete esetén a zónáknak riasztani kell a vezérlést. Ennek ellenére a zóna[1] nem riasztás( zóna[1]), hanem csak észleltVáltozás(zóna[1]) üzenetet küld a vezérlésnek. Hogyan lehetséges ez? 4. A diagramon csak egy helyen, az észleltVáltozás(zóna[1]) üzenet elıtt áll magyarázó ırszem. Annak mintájára milyen magyarázó ırszem illene a zóna[2] példaobjektum élesítve :=1 alakú (ál)öndelegációja elé?
Úgy, hogy amelyik boolean típusú értéket kap, az a vezérlés attribútuma, amelyik szám típusú értéket kap, az meg a zóna[2], illetve a zóna[3] objektumé. A típusok eltérése pontosan megfelel annak, hogy a Zóna osztályban az élesítve attribútum típusa int, a Vezérlésben pedig boolean. Úgy, hogy a zóna[1] egyáltalán nincs élesítve, mert a legutolsó élesítés alól ki lett iktatva.
[élesítve=0 ÉS kiiktatva=false]
4.4.6 A zónák, a vezérlés és a kapcsolótáblák együttmőködése Olyan részleteket, amelyeket a 4.23. ábra állapotdiagramja rejtve hagy (lásd a 4.4.4. szakasz 5. kérdésére adott választ), más módon lehet kifejteni. Például pszeudokóddal vagy – ahogy itt következik – szekvenciadiagrammal. A 4.25. ábra a zónák, a vezérlés és a kapcsolótáblák együttmőködésének – mások mellett – ilyen esetét is mutatja (lásd a keretezett részben). A 4.25. ábra példaobjektumai között a lakás zónáiból csak a zóna[1] és a zóna[2] szerepel, mert a bemutatni kívánt esetek csak ezt a két zónát érintik. Az érzékelıZ1 a zóna[1] érzékelıje, az érzékelıMZ2 és az érzékelıNyZ2 pedig a zóna[2]-höz tartoznak. – A kapcsolótáblákból is csak egy példaobjektumot vettünk fel a diagamra, mert a lényegen az sem változtatna, ha több lenne ott: akkor némely, itt egyszer szereplı üzeneteketeket a modelbe felvett mindegyik kapcsolóTábla objektumra meg kellene ismételni. A 4.25. ábrán mutatott kommunikációt tekintsük a 4.24. ábrán elmesélt történet folytatásának, azaz a zóna[1] kiiktatott, a zóna[2] pedig otthontartózkodással élesített állapotban kezdi / folytatja mőködését. – Pontosabban technikai okokból kifolyólag van némi szakadás a két ábra között a történések sorozatában: Az utóbbi ábra egy getÜzemképes() üzenettel kezdıdik, amelyet egy zóna nem akármikor küld az érzékelıinek, hanem csak az órajel eseményt jelentı rendszermegszakítás hatására. Ráadásul ezt az eseményt az összes zóna feldolgozza, és hatására minden zóna az összes érzékelıjét lekérdezi a getÜzemképes() üzenet útján. Azonban a példaobjektumok körét nem kívántuk az órajelet adó operációs rendszerrel, valamint a getÜzemképes() üzenetben érintett összes zónával és érzékelıvel kibıvíteni. Ugyanis itt egy érzékelı üzemképtelenné válásának a következményei érdekelnek minket, nem pedig azok az elızmények, amelyek miatt a zóna lekérdezi az érzékelıi állapotát.
EGY LAKÁS BIZTONSÁGI RENDSZERE
169
4.25. ábra: Szekvenciadiagram a zónák, a vezérlés és a kapcsolótáblák együttmőködésérıl
Ellenırzı/magyarázó kérdések (a kérdések a 4.25. ábrára vonatkoznak): 1. Az érzékelıZ1-hez intézett getÜzem- Mert a zóna[1] kiktatott állapotban van. képes() kérdésre adott false válasz miatt miért nem riasztja a zóna[1] a vezérlést? Mert a zóna[2] otthon tartózkodással 2. A zóna[2] az érzékelıMZ2-tıl van élesítve (erre hívja fel a figyelmet az érkezı riasztásM() esemény hatására [élesítve=1] ırszem), és ilyen állapotmiért nem egy riasztás(zóna[2]) ban a mozgásérzékelık jelzéseire nem kell üzenetet küld a vezérlésnek? riasztani a rendszert. (Csak a kapcsolótábla megfelelı ledjének kell mutatnia, hogy mozgás van az adott zónában.) A zóna[2]-tıl érkezı riasztás( 3. Milyen részleteket rejt magába a VeZóna[2]) esemény bekeretezett követzérlés osztály riasztás(pZóna) példánymővelete? kezményeit. Ezek: a) riasztás(zónaIndex) üzenet (a konkrét esetben riasztás(2) üzenet) küldése a kapcsolóTábla objektumnak (objektumoknak); b) a hangjelzés (sziréna) bekapcsolása; c) riasztás üzenet küldése a biztonsági szervezet rendszerének.
170
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4. A hangjelzés bekapcsolását (az ábrán: hangot bekapcsol) miért a vezérlés öndelegációjaként ábrázoltuk?
Mert a diagramon nincs olyan példaobjektum, amelynek a bekapcsoló jelet / parancsot elküldhetné. – De mi lehetne a címzett szerepét betöltı példaobjektum? – A felhasználói alkalmazások általában nem közvetlenül kezelik a hardverkomponenseket (itt a szirénát), ide egy az operációs rendszernek szóló rendszerhívást kell elképzelni.
4.4.7 A Vezérlés és a KapcsolóTábla osztályok specifikációjának kiegészítése A probléma statikus modelljének utolsó változtatását a 4.21. ábrán ejtettük meg. Itt a dinamikus modellezés útján azóta feltárt új elemekkel a Vezérlés és a KapcsolóTábla osztályok specifikációját egészítjük ki. A Vezérlés 4.23. ábra szerinti állapotdiagramján elıször megjelent élesítve attribútum a Vezérlés-példányok élesített állapotának megkülönböztetésére született, tehát ez a Vezérlés osztály egy új példányattribútuma. Az ugyanezen diagramon látható kapcsolóTábla.változásJelzés( zónaIndex) kapcsolóTábla.üzemképtelenJelzés( zónaIndex)
akciókból következik, hogy a KapcsolóTábla osztálynak rendelkezni kell az akciókban küldött üzenetekkel azonos nevő (azonos szignatúrájú) mőveletekkel.
4.26. ábra: A Vezérlés és a KapcsolóTábla osztályok specifikációjának bıvítése
A 4.26. ábrán a KapcsolóTábla osztály specifikációja azért ennyire szegényes, mert a kapcsolótáblákkal közvetlenül nem foglalkoztunk, így az osztályuknak csak azokra a mőveleteire derült fény, amelyekre a vezérlésnek a kapcsolótáblákhoz intézett üzenetei utaltak. A kapcsolótábla modellezését azért mellıztük, mert felhasználói felület kezelésével (a jegyzet terjedelméhez képest) már éppen eleget foglalkoztunk a digitális óra és a zsebszámológép problémák tárgyalásánál. – Ha az Olvasó mégis megpróbálkozna vele, vegye számításba, hogy az elızı esettanulmányokban a digitális órának és a zsebszámológépnek csak a szoftveres szimulációját terveztük meg, itt viszont a kapcsolótábla egy fizikailag létezı komponens (egy hardver, egy perifériális egység). A kapcsolóTábla szoftverobjektum itt nem arra való, hogy egy kapcsolótáblát szimuláljon, hanem arra, hogy a fizikailag létezı kapcsolótáblával folytatott kommunikációt lebonyolítsa, illetve a rendszer elıl eltakarja azt az
EGY LAKÁS BIZTONSÁGI RENDSZERE
171
körülményt, hogy többféle kapcsolótábla van forgalomban, amelyek eltérı módokat kínálnak a rendszerrel való üzenetváltásokra, valamint a rendszerállapotok kijelzésére.
172
OBJEKTUMORIENTÁLT TERVEZÉS – ESETTANULMÁNYOK
4.5 Folytassa az Olvasó! Ha a rendszert az idáig készült (a kapcsolótábla modelljével is kiegészített) tervek alapján valósítják meg, a megvalósított alkalmazás tesztelıi egy furcsa jelenséget fognak tapasztalni: A rendszer nem élesített állapotában egy idı után a kapcsolótábla bizonyos zónaledjei vagy esetleg az összes zónaled folyamatosan azt fogja jelezni, hogy a neki megfelelı zónában változás észlelhetı, dacára annak, hogy senki nem tartózkodik abban a zónában, senki sem nyitogatja ott az ablakokat és az ajtókat. A fejlesztık alapos nyomkövetéssel kiderítik, hogy az illetı zónák nem kapnak se riasztásM(), se riasztásNy() üzenetet az érzékelıiktıl, és ık sem küldenek észleltVáltozás(pZóna) üzenetet a vezérlésnek, sıt a vezérlés sem küld változásJelzés(zónaIndex) üzenetet a kapcsolótáblának, a legutóbbin az illetı zóná(k)hoz tartozó led(ek) mégis úgy világít(anak), mintha a kapcsolótábla a megfelelı zónaIndex paraméterrel változásJelzés(zónaIndex) üzenetet kapott volna. – Akkor rájönnek, a jelenség oka az lehet, hogy a kapcsolótábla valamikor tényleg kapott ilyen üzenetet, amikor valaki tényleg a zónában tartózkodott, de azt hiába hagyta el már régen, a rendszer mégsem gondoskodott a megfelelı zónaled kikapcsolásáról. A tervezı tehát azt a mulasztást követte el, hogy csak változásJelzés(…) üzenetetet tervezett, de a jelzések megszőnésekor a jelzés hatásának kikapcsolásáról megfeledkezett. – Az Olvasóra bízzuk, hogy pótolja a tervezésnek ezt a hiányosságát. Fontolja meg, hogy a Zóna, a Vezérlés és a KapcsolóTábla osztályok közül melyikre bízná a jelzés kikapcsolásáról való gondoskodást!