Programozás II. ATM példa Dr. Iványi Péter 1
ATM gép ATM=Automated Teller Machine Pénzkiadó automata Kezelő szoftvert szeretnénk írni Objektum-orientált módon 2
Követelmények Egyszerre csak egy embert szolgál ki Be kell tenni egy kártyát és be kell írni a PIN kódot Ezeket majd a bank ellenőrzi Ezután több tranzakciót lehet végrehajtani A kártyár csak akkor adjuk vissza ha befejezte a műveleteket 3
Tranzakciók Követelmények Lehessen kivenni pénzt az automatából Lehessen lekérni a számlán levő összeget A bankban mindig ellenőrizni kell hogy a tranzakció érvényes-e Ha rossz PIN kódot gépeltünk be, három lehetőségünk van, ha harmadikra sem sikerült a gép megtartja a kártyát Ha valamiért rossz a tranzakció a gép kijelzi 4
Követelmények Egy operátor kikapcsolhatja és bekapcsolhatja a gépet Kellene egy log (rögzítő) mechanizmus, ami mindent műveletet tárol Számlát ad a műveletek után 5
ATM rendszer ATM 6
Indítás Események A rendszert be kapcsolja az operátor és feltölti pénzzel Leállítás Ha nem használja senki a gépet ki lehet kapcsolni a gépet Megszakad a kapcsolat a bankkal 7
8
9
Session Események Beraknak egy kártyát a gépbe A gép behuzza és megpróbálja olvasni Ha hiba van visszaadja Be kell gépelni a PIN kódot Menüből választva megadhatunk egy tranzakciót Minden tranzakció után megkérdezzük folytassuk-e Ha nem, ki kell adni a kártyát 10
11
Tranzakció Események Absztrakt osztály, mindegyik tranzakció egy kicsit más Akkor használjuk amikor a menüből választottunk egy műveletet A tranzakció adatait egy üzenetben küldjük el a banknak Ha a bank jóvá hagyja, akkor végrehajtja az ATM Ha a bank szerint rossz a PIN, újra be lehet írni, max háromszor 12
13
Pénz kivétel Események Bekérjük hogy mennyi pénzt akar kivenni Ellenőrizzük, hogy van-e elég pénz a számlánkon Ha igen Ellenőrizzük, hogy van-e elég pénz az automatában Ha minden rendben kiadjuk a pénzt 14
Lekérdezés Események A műveletet elküldjük a banknak, és ha minden rendben a bank visszaküldi az információt 15
16
void main()... InetAddr inet(136, 155, 18, 20); // hozzuk letre a gepet ATM gep(42, "Rokus utca", "OTP", inet); while(true) gep.run(); ATM gépen futó program 17
class ATM int id; string place; string bankname; InetAddr bankaddress; // a gep komponensei CardReader *reader; PenzKiado *penzkiado; Nyomtato *nyomtato; // allapot informacio, milyen allapotban van a gep ATM_STATE allapot; bool on; Session *aktualis;... 18
ATM id place bankname bankaddress reader penzkiado nyomtato allapot on aktualis +ATM +getreader +getnyomtato +getpenzkiado +bekapcsol +kikapcsol +run UML osztálydiagram 19
UML diagramok 20
penzkiado ATM reader nyomtato 21
Állapot diagram KIKAPCSOLVA kikapcsol bekapcsolás KISZOLGÁLÁS kártya be / session létrehozás kártya ki / session vége VÁRAKOZÁS 22
void run() switch(allapot) case KIKAPCSOLVA:... break; case VARAKOZAS:... break; case KISZOLGALAS:... break; 23
case KIKAPCSOLVA: cout << "OPERATOR: ATM nem elerheto!" << endl; cout << "OPERATOR: Bekapcsoljuk? [i/n]" << endl; cin >> be; if(be == 'i') int pp; bekapcsol(); // toltsuk fel a gepet penzzel cout << "OPERATOR: Mennyi penzt tegyunk bele? " << endl; cin >> pp; getpenzkiado()->feltolt(pp); allapot = VARAKOZAS; break; 24
case VARAKOZAS: if(this->getreader()->kartya_olvas() == NULL)... // Tegye be a kartyat! cin >> be; if(be == 'i') cin >> pin; Kartya *k = new Kartya(pin); this->getreader()->kartya_betesz(k); if(this->getreader()->kartya_olvas()) aktualis = new Session(this); allapot = KISZOLGALAS; break; 25
case KISZOLGALAS: aktualis->kiszolgal(); allapot = VARAKOZAS; break; 26
pénz penzkiado ATM reader nyomtato kartya session 27
enum SESSION_STATE KARTYAT_OLVAS, PINT_OLVAS, TRANZAKCIO_VALASZTAS, TRANZAKCIO_VEGREHAJTAS, KARTYA_KIDOB, VEGE ; class Session private: SESSION_STATE allapot; ATM *atm; public: Session(ATM *a) : atm(a) allapot = KARTYAT_OLVAS; void kiszolgal(); ; 28
Állapot diagram KÁRTYÁT_OLVAS sikertelen újabb tranzakció sikerült kilépés PINT_OLVAS sikerült TRANZAKCIÓT_VÁLASZT választott vége TRANZAKCIÓT_VÉGREHAJT tranzakció vége KÁRTYÁT_KIDOB VÉGE 29
void kiszolgal() while(allapot!= VEGE) switch(allapot) case KARTYAT_OLVAS:... break; case PINT_OLVAS:... break; case TRANZAKCIO_VALASZTAS:... break; case TRANZAKCIO_VEGREHAJTAS:... break; case KARTYA_KIDOB:... break; 30
case KARTYAT_OLVAS: kartya = atm->getreader()->kartya_olvas(); if(kartya!= NULL) allapot = PINT_OLVAS; else atm->getnyomtato()->nyomtat("kartya nem olvashato"); allapot = KARTYA_KIDOB; break; 31
case PINT_OLVAS: pin=-2; while(pin > 9999 pin < -1) atm->getnyomtato()->nyomtat( Azonosito? (-1 = kilepes):"); cin >> pin; if(pin == -1) allapot = KARTYA_KIDOB; else allapot = TRANZAKCIO_VALASZTAS; break; 32
case TRANZAKCIO_VALASZTAS: int tipus; while(1) atm->getnyomtato()->nyomtat("valasszon muveletet: ");... // menü cin >> tipus; if(tipus < 1 tipus > 3) atm->getnyomtato()->nyomtat("hiba: Ervenytelen muvelet"); else break; 33
switch(tipus) case 1: t = new Tranzakcio_Kivesz(atm, this, kartya, pin); allapot = TRANZAKCIO_VEGREHAJTAS; break; case 2: t = new Tranzakcio_Info(atm, this, kartya, pin); allapot = TRANZAKCIO_VEGREHAJTAS; break; case 3: allapot = KARTYA_KIDOB; break; break; 34
pénz penzkiado ATM reader nyomtato kartya session tranzakcio info kivesz 35
case TRANZAKCIO_VEGREHAJTAS: bool ismet; ismet = t->vegrehajt(); delete t; if(ismet) allapot = TRANZAKCIO_VALASZTAS; else allapot = KARTYA_KIDOB; break; 36
class Tranzakcio protected: ATM *atm; Session *session; Kartya *kartya; int pin; static int ser_num; public: Tranzakcio(ATM *a, Session *s, Kartya *k, int p) : atm(a), session(s), kartya(k), pin(p) ser_num++; virtual bool vegrehajt() = 0; ; int Tranzakcio::ser_num = 0; 37
class Tranzakcio_Info : public Tranzakcio public: Tranzakcio_Info(ATM *a, Session *s, Kartya *k, int p) : Tranzakcio(a, s, k, p) bool vegrehajt() Uzenet *u; u = new Uzenet(LEKERDEZES, kartya, pin, ser_num, -1, -1, Penz(-1)); // Ide jon az a kod, amit uzenetet kuld a // banknak a halozaton keresztul Status *ered; ered = OTP.uzenet_kezeles(*u); if(ered->sikeres() == false) atm->getnyomtato()->nyomtat("hiba: "); atm->getnyomtato()->nyomtat(ered->getuzenet()); delete ered; delete u; char c; atm->getnyomtato()->nyomtat("ismet? [i/n]");... ; 38
class Status bool siker; string uzenet; public: Status(bool s=false, string u="") : siker(s), uzenet(u) bool sikeres() return siker; string getuzenet() return uzenet; ; 39
class Siker : public Status public: Siker(string u="") : Status(true, u) ; class ErvenytelenPIN : public Status public: ErvenytelenPIN() : Status(false, "Ervenytelen PIN") ;... 40
pénz nyomtato penzkiado ATM session reader tranzakcio kartya info kivesz siker hálózat uzenet status ervenytelenpin ervenytelenuzenet szamlak bank 41