Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Általános szoftver architektúrák. Giachetta Roberto

Hasonló dokumentumok
Általános szoftver architektúrák

Eseményvezérelt alkalmazások fejlesztése I 12. előadás. Összetett szoftver architektúrák. Giachetta Roberto

3. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája

Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája. Grafikus felületű alkalmazások architektúrája

Modell megvalósítása. Gregorics Tibor: Eseményvezérelt alkalmazások fejlesztése I.

ELTE, Informatikai Kar december 12.

Webes alkalmazások fejlesztése 10. előadás. Webszolgáltatások tesztelése (ASP.NET Core) Cserép Máté

Szoftvertechnolo gia gyakorlat

2. Beadandó feladat dokumentáció

Programozási technológia 2.

2. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

Komponens alapú szoftverfejlesztés 8. előadás. Szoftver architektúrák alapvetései. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Eseményvezérelt alkalmazások fejlesztése II 8. előadás. Összetett WPF alkalmazások. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Java Programozás 11. Ea: MVC modell

1. Beadandó feladat dokumentáció

Webes alkalmazások fejlesztése 7. előadás. Autentikáció és autorizáció (ASP.NET)

Programozási technológia II 3. előadás. Objektumorientált tervezés Giachetta Roberto

Webes alkalmazások fejlesztése 8. előadás. Webszolgáltatások megvalósítása (ASP.NET WebAPI)

S01-7 Komponens alapú szoftverfejlesztés 1

Elemi alkalmazások fejlesztése IV.

MySql elindítása. Elemi alkalmazások fejlesztése IV. Feladat. Az alkalmazás adatbázisa

3. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Adatbázis-kezelés modell/nézet architektúrában

Szoftvertechnológia 5. előadás. Objektumorientált tervezés: architektúra. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

és az instanceof operátor

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Cserép Máté

Eseményvezérelt alkalmazások fejlesztése I 10. előadás. Adatbázis-kezelés modell/nézet architektúrában. Giachetta Roberto

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

Excel ODBC-ADO API. Tevékenységpontok: - DBMS telepítés. - ODBC driver telepítése. - DSN létrehozatala. -Excel-ben ADO bevonása

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

WCF, Entity Framework, ASP.NET, WPF 1. WCF service-t (adatbázissal Entity Framework) 2. ASP.NET kliens 3. WPF kliens

Szoftverarchitektúrák 3. előadás (második fele) Fornai Viktor

A Java EE 5 plattform

Java. Perzisztencia. ANTAL Margit. Java Persistence API. Object Relational Mapping. Perzisztencia. Entity components. ANTAL Margit.

Java programozási nyelv 5. rész Osztályok III.

Se S r e ial a iza z t a ion o n (in n Ja J v a a v ) a Szerializáció

ZH mintapélda. Feladat. Felület

2. Beadandó feladat dokumentáció

Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem

Földmérési és Távérzékelési Intézet

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET)

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Webes alkalmazások fejlesztése 12. fejezet. Szolgáltatás alapú kommunikáció (WCF) Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Adatbázis, adatbázis-kezelő

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET) Cserép Máté.

Elemi alkalmazások fejlesztése III.

OOP: Java 8.Gy: Abstract osztályok, interfészek

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

Webes alkalmazások fejlesztése 10. előadás. Szolgáltatás alapú rendszerek megvalósítása (ASP.NET WebAPI) Cserép Máté

Enterprise JavaBeans. Ficsor Lajos Általános Informatikai Tanszék Miskolci Egyetem. Az Enterprise JavaBeans

2. Beadandó feladat dokumentáció

3. Beadandó feladat dokumentáció

Objektumorientált paradigma és programfejlesztés Bevezető

ISA szimulátor objektum-orientált modell (C++)

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

Szerializáció. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Szerializáció / 22

Models are not right or wrong; they are more or less useful.

Webes alkalmazások fejlesztése 1. előadás. Webes alkalmazások és biztonságuk

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

Enterprise JavaBeans 1.4 platform (EJB 2.0)

Alkalmazás technológiai frissítés migrációs és üzemeltetési tapasztalatok

OOP #14 (referencia-elv)

Grafikus felhasználói felületek. Dr. Szendrei Rudolf Informatikai Kar Eötvös Loránd Tudományegyetem. Programozási technológia I. Dr.

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

Szoftvertechnológia 6. előadás. Objektumorientált tervezés: állapotkezelés. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET Core) Cserép Máté

Sorosítás (szerializáció) és helyreállítás. 1. Bináris sorosítás és helyreállítás Szükséges névterek Attribútumok. 1.3.

Szoftvertechnológia 8. előadás. Szoftverrendszerek tervezése. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Adatkezelés speciális eszközökkel. Giachetta Roberto

3. Osztályok II. Programozás II

Szoftvertechnológia 7. előadás. Objektumorientált tervezés: végrehajtás. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Elemi Alkalmazások Fejlesztése Beadandó Feladat Juhász Ádám

Programozási alapismeretek 4.

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Entity Framework alapú adatbáziselérés

Webes alkalmazások fejlesztése 7. előadás. Autentikáció és autorizáció (ASP.NET Core) Cserép Máté

Programozási technológia II 6. előadás. Objektumorientált tervezési szempontok és minták

Szoftverfejlesztő képzés tematika oktatott modulok

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Android Wear programozás. Nyitrai István

Alkalmazott Modul III 6. gyakorlat. Objektumorientált programozás: öröklődés és polimorfizmus

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

1. Az Access 2000 indítása után válasszuk az Üres adatbázis létrehozása pontot,

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

DCOM Áttekintés. Miskolci Egyetem Általános Informatikai Tanszék. Ficsor Lajos DCOM /1

Java és web programozás

Már megismert fogalmak áttekintése

Objektumorientált paradigma és a programfejlesztés

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Eseményvezérelt alkalmazások fejlesztése I 8. előadás Általános szoftver architektúrák Giachetta Roberto http://people.inf.elte.hu/groberto

Szoftverek architektúrája Szoftver architektúrának nevezzük a szoftver fejlesztése során meghozott elsődleges tervezési döntések halmazát az architektúra létrehozása során mintákra hagyatkozunk, a szoftver teljes architektúráját definiáló mintákat nevezzük architekturális mintáknak (architectural pattern) a legegyszerűbb felépítést a monolitikus architektúra adja, amelyben nincsenek szétválasztva a funkciók a legegyszerűbb felbontás a felhasználói felület leválasztása a háttérbeli tevékenységekről, ezt nevezzük modell/nézet (MV, model-view) architektúrának más néven kétrétegű (two-tier) architektúra, ahol a két réteg egymásra épül, vertikálisan ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:2

Perzisztencia Az adatkezelésnek egy fontos része az adatok tárolása egy perzisztens (hosszú távú) adattárban az adattár lehet fájlrendszer, adatbázis, hálózati szolgáltatás, stb. az adattárolás formátuma lehet egyedi (bináris, vagy szöveges), vagy valamilyen struktúrát követő (XML, JSON, ) annak függvényében, hogy az adatokat meg szeretnénke osztani már szoftverekkel a kétrétegű architektúrában a perzisztens adattárolás is a modell feladata, hiszen a modell adatait kell megfelelően eltárolnunk ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:3

Példa Feladat: Készítsünk egy Tic-Tac-Toe programot, amelyben két játékos küzdhet egymás ellen. lehetőséget adunk játékállás elmentésére (Ctrl+L) és betöltésére (Ctrl+S), ehhez a felhasználó 5 mentési hely közül választhat (egy külön ablakban) a mentést egyszerű szöveges fájlban végezzük (game1.sav,, game5.sav), elmentjük a lépésszámot, a soron következő játékost és a tábla állását ehhez létrehozunk egy betöltésre és egy mentésre szolgáló ablakot (SaveGameWidget, LoadGameWidget), a modellt pedig kiegészítjük a műveletekkel (savegame, loadgame), valamint a játéklista lekérdezésével (savegamelist) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:4

Példa Tervezés (architektúra): TicTacToeWidget QWidget - _stepnumber :int - _currentplayer :Player - _gametable :Player** TicTacToeModel -_model QObject -_loadgamewidget LoadGameWidget + LoadGameWidget(QWidget*) + okbutton_clicked() :void + TicTacToeModel() + ~TicTacToeModel() + newgame() :void + stepgame(int, int) :void + loadgame(int) :bool + savegame(int) :bool + savegamelist() :QVector<QString> {query} + stepnumber() :int {query} + currentplayer() :Player {query} + getfield(int, int) :Player {query} + gamewon(tictactoemodel::player) :void + gameover() :void + fieldchanged(int, int, TicTacToeModel::Player) :void - checkgame() :void -_savegamewidget SaveGameWidget # _okbutton :QPushButton* # _cancelbutton :QPushButton* # _listwidget :QListWidget* QDialog + SaveGameWidget(QWidget*) + setgamelist(qvector<qstring>) :void + selectedgame() :int {query} ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:5

Példa Megvalósítás (tictactoemodel.cpp): bool TicTacToeModel::saveGame(int gameindex){ QFile file("game" + QString::number(gameIndex) + ".sav"); if (!file.open(qfile::writeonly)) return false; } QTextStream stream(&file); // soronként egy adatot írunk ki stream << _stepnumber << endl; stream << (int)_currentplayer << endl; return true; ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:6

A háromrétegű architektúra Igazából a perzisztens adatkezelés formája, módja nem függ a modelltől, ezért könnyen leválasztható róla, függetleníthető a leválasztás lehetővé teszi, hogy a két komponenst egymástól függetlenül módosítsuk, vagy cseréljük, és egy komponensnek se kelljen több dologért felelnie (single responsibilty principle) Ez elvezet minket a háromrétegű (three-tier) architektúrához, amelyben elkülönül: a nézet (presentation/view tier, presentation layer) a modell (logic/application tier, business logic layer) a perzisztencia, vagy adatelérés (data tier, data access layer, persistence layer) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:7

A háromrétegű architektúra alkalmazás felhasználó nézet (megjelenítés, eseménykezelés) modell (logika, állapotkezelés) adattár perzisztencia (adatmentés, betöltés) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:8

Példa Feladat: Készítsünk egy Tic-Tac-Toe programot háromrétegű architektúrában. leválasztjuk az adatelérést a modellről egy új osztályba (TicTacToeDataAccess), amely biztosítja a három adatkezelési műveletet (savegame, loadgame, savegamelist) az adatok modell és adatelérés közötti egyszerű kommunikációja érdekében az adatelérési réteg egészek vektorát fogja kezelni, amely 11 értéket tárol a korábbi sorrendnek megfelelően (lépésszám, játékos, mezők sorfolytonos sorrendben) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:9

Példa Tervezés: TicTacToeModel - _stepnumber :int - _currentplayer :Player - _gametable :Player** - _dataaccess :TicTacToeDataAccess QObject + TicTacToeModel() + ~TicTacToeModel() + newgame() :void + stepgame(int, int) :void + loadgame(int) :bool + savegame(int) :bool + savegamelist() :QVector<QString> {query} + stepnumber() :int {query} + currentplayer() :Player {query} + getfield(int, int) :Player {query} - checkgame() :void «signal» + gamewon(tictactoemodel::player) :void + gameover() :void + fieldchanged(int, int, TicTacToeModel::Player) :void -_dataaccess TicTacToeDataAccess + TicTacToeDataAccess() + savegamelist() :QVector<QString> {query} + loadgame(int, QVector<int>&) :bool + savegame(int, QVector<int>&) :bool ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:10

Példa Megvalósítás (tictactoemodel.cpp): bool TicTacToeModel::saveGame(int gameindex) { QVector<int> savegamedata; // összerakjuk a megfelelő tartalmat savegamedata.push_back(_stepnumber); savegamedata.push_back((int)_currentplayer);... } return _dataaccess.savegame(gameindex, savegamedata); // az adatelérés végzi a tevékenységeket ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:11

Példa Feladat: Készítsünk egy Tic-Tac-Toe programot háromrétegű architektúrában. módosítsuk úgy az adatkezelést, hogy az adatok tárolása adatbázisban történjen, a game adatbázis games táblájában továbbra is 5 mentési hely lesz, és az adatokat is a korábbiaknak megfelelően mentjük (mivel nincs utolsó módosítás dátuma, ezért a mentés időpontját is a táblázatba írjuk) ehhez csupán az adatelérést kell módosítanunk, a program többi része változatlan marad, felhasználjuk a Qt adatbázis modult (QSqlDatabase, QSqlQuery) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:12

Példa Megvalósítás (tictactoedataaccess.cpp): bool TicTacToeDataAccess::loadGame(int gameindex, QVector<int> &savegamedata) { QSqlQuery query; query.exec("select stepcount, currentplayer, tabledata from games where id = " + QString::number(gameIndex)); // betöltjük a mentés egyes elemeit savegamedata[0] = query.value(0).toint(); savegamedata[1] = query.value(1).toint(); } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:13

Függőségek Egy több rétegű architektúrában a rétegek (modulok) felhasználják az alattuk lévő réteg funkcionalitását, azaz a saját funkcionalitásuk függ az alattuk lévő rétegtől A függőségnek (dependency, coupling) több formája és szintje lehet általában a cél a minél kisebb függőség elérése (loose coupling) a rétegek között, jól definiált felületek (interfészek) mentén több réteg esetén a függőségek láncot alkotnak függőség miatt számos probléma felmerülhet (pl. túl sok függőség, hosszú láncok, ütközések, körkörös függőségek) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:14

Függőségek Pl.: class Service { // egy osztály, ami biztosít egy szolgáltatást public: void Provide() { } } class Client { // egy osztály, amely felhasználja // a szolgáltatást (kliens) private: Service _service; // így függőség alakul ki public: void Run() { _service.provide(); } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:15

Függőségek kezelése A függőségeket úgy kell megvalósítanunk, hogy a felhasznált osztály konkrét megvalósításától ne, csak felületétől (interfészétől) függjön (dependency inversion principle) a megvalósítás a körülmények függvényében könnyen változtatható legyen pl. az adatkezelést csak akkor végezhetjük adatbázisban, amennyiben az rendelkezésünkre áll Ennek megfelelően a függőségeket mindig általános formában (interfész, vagy absztrakt osztály) kell kezelnünk ez érvényes minden modulra az architektúrában ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:16

Függőségek kezelése Pl.: class ServiceInterface { // egy osztály, ami biztosít egy szolgáltatás // felületet public: void Provide() = 0; } class ConcreteService : public ServiceInterface { // egy osztály, ami megvalósítja a // szolgáltatást public: void Provide() { } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:17

Függőségek kezelése class Client { private: ServiceInterface *_service; // a függőség csak a felületre vonatkozik public: MyClass(ServiceInterface *s) { _service = s; } // valahol megadjuk, mi lesz a felhasznált // szolgáltatás void Run() { _service->dosomething(); } // a megvalósítás fog végrehajtódni } Client client(new ConcreteService()); // átadjuk a konkrét megvalósítást ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:18

Függőségek kezelése A modulok tehát a függőségeknek csak az absztrakcióját látják, a konkrét megvalósítást külön adjuk át nekik, ezt nevezzük függőség befecskendezésnek (dependency injection) a befecskendezés helye/módszere függvényében lehetnek különböző típusai (pl. konstruktor, metódus, interfész) Client - service :Service + Client(Service) «interface» Service ConcreteService ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:19

Példa Feladat: Készítsünk egy Tic-Tac-Toe programot háromrétegű architektúrában. a program alapértelmezetten az adatbázist használja mentésre, de amennyiben az nem elérhető, használjon fájl alapú adatkezelést az adatelérés befecskendezzük a modellbe, és a nézet fogja megállapítani, milyen adatelérést adunk át az adatelérés osztályunk absztrakt lesz, és származtatjuk belőle a fájl (TicTacToeFileDataAccess) és adatbázis (TicTacToeDbDataAccess) alapú elérést az osztály kiegészül a rendelkezésre állás lekérdezésével (isavailable) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:20

Példa Tervezés: QObject TicTacToeModel -_dataaccess TicTacToeDataAccess + TicTacToeDataAccess() + ~TicTacToeDataAccess() + isavailable() :bool {query} + savegamelist() :QVector<QString> {query} + loadgame(int, QVector<int>&) :bool + savegame(int, QVector<int>&) :bool TicTacToeDbDataAccess + TicTacToeDbDataAccess() + ~TicTacToeDbDataAccess() + isavailable() :bool {query} + savegamelist() :QVector<QString> {query} + loadgame(int, QVector<int>&) :bool + savegame(int, QVector<int>&) :bool TicTacToeFileDataAccess + TicTacToeFileDataAccess() + ~TicTacToeFileDataAccess() + isavailable() :bool {query} + savegamelist() :QVector<QString> {query} + loadgame(int, QVector<int>&) :bool + savegame(int, QVector<int>&) :bool ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:21

Példa Megvalósítás (tictactoewidget.cpp): TicTacToeWidget::TicTacToeWidget(QWidget *parent) : QWidget(parent) { // az adatkezelést itt döntjük el _dataaccess = new TicTacToeDbDataAccess(); // alapértelmezetten adatbázist használunk if (!_dataaccess->isavailable()){ // de ha az nem elérhető _dataaccess = new TicTacToeFileDataAccess(); // átváltunk fájlra } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:22

Többrétegű alkalmazások megvalósítása A függőség befecskendezés a fejlesztés során is nagyobb szabadságot ad, mivel elég a felhasznált osztály interfészét megadni az a függő osztály fejlesztéséhez tehát a függő osztály implementációját nem zavarja a konkrét megvalósítás hiánya azonban tesztelés csak akkor hajtható végre, ha a konkrét megvalósítás adott, ez lassíthatja a fejlesztést továbbá egységtesztek esetén problémát jelenthet, ha a felhasznált osztály megvalósítása hibás, mivel így az a függő osztály is hibás viselkedést produkál (noha a hiba másik osztályban található) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:23

Mock objektumok Megoldást jelent, ha nem támaszkodunk a felhasznált osztály megvalósítására, hanem biztosítunk egy olyan megvalósítást, amely szimulálja annak működését implementálja a felületet, így felhasználható a függő osztályban egyszerű viselkedést biztosít, amelynek célja, hogy a függő osztály tesztelésére lehetőséget adjon garantáltan hibamentes, így az egységteszt során valóban csak a tényleges hibákra derül fény A szimulációt megvalósító objektumokat nevezzük mock objektumoknak ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:24

Mock objektumok Pl.: class ServiceMock : public ServiceInterface { // mock-olást megvalósító osztály public: void Provide() { qdebug() << "Running service."; } // amely egy egyszerű implementációt biztosít } Client client(new ServiceMock()); // ezt felhasználjuk, így már tesztelhetjük az // osztályunkat ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:25

Példa Feladat: Teszteljük le a Tic-Tac-Toe játék háromrétegű megvalósításának modelljét. a modell függ az adateléréstől, de azt nem akarjuk tesztelni, ezért viselkedését kiváltjuk egy mock objektummal létrehozunk egy tesztprojektet, amelyben bemásoljuk a TicTacToeModel, valamint TicTacToeDataAccess osztályokat létrehozunk egy mock objektumot az adatelérésre (TicTacToeDataAccessMock), amely egyszerű funkciókat biztosít, és a konzolra (qdebug) üzen, ennek egy példányát felhasználjuk a tesztben ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:26

Példa Megvalósítás (tictactoedataaccessmock.h): class TicTacToeDataAccessMock : public TicTacToeDataAccess // mock objektum, csak teszteléshez { bool savegame( ) { // játék mentése qdebug() << "game saved to slot (" << gameindex << ") with values: "; for (int i = 0; i < 11; i++) qdebug() << savegamedata[i] << " "; } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 8:27