komponens alapú szoftverfejlesztés 9. előadás grafikus felületű … · 2016-12-02 ·...
Post on 10-Jul-2020
1 Views
Preview:
TRANSCRIPT
Eötvös Loránd Tudományegyetem
Informatikai Kar
Komponens alapú
szoftverfejlesztés
Giachetta Roberto
groberto@inf.elte.hu
http://people.inf.elte.hu/groberto
9. előadás
Grafikus felületű alkalmazások
architektúrái
Grafikus felületű alkalmazások architektúrái
• A grafikus felületű (graphical user interface) alkalmazások jelentős
részét képezik a mai szoftvereknek
• közvetlenül a felhasználóval állnak kapcsolatban, aki számára
információkat jelenítenek meg, és feldolgozzák a felhasználói
bemenetet, amihez eseményvezérlést használnak
• általánosan megfogalmazott grafikus elemekből (vezérlőkből)
alkalmazás specifikus specifikus űrlapokat állítanak össze
• Grafikus felületű alkalmazások esetén a leggyakoribb felépítés a
háromrétegű (3-tier) architektúra, amelyben elkülönül a nézet, a
modell és a perzisztencia
• a nézet tartalmazza az adatok megjelenítésének módját, valamint
a felhasználói interakció feldolgozását
ELTE IK, Komponens alapú szoftverfejlesztés 9:2
A grafikus felületű alkalmazás
Grafikus felületű alkalmazások architektúrái
• A háromrétegű alkalmazásokban az adatok három állapotban
jelennek meg
• megjelenített állapot (display state): a felhasználói felületen
megjelenő tartalomként, amelyet a felhasználó módosíthat
• munkafolyamat állapot (session state): a memóriában, amely
mindaddig elérhető, amíg a program és felhasználója aktív
• rekord állapot (record state): az adat hosszú távon megőrzött
állapota az adattárban (perzisztenciában)
ELTE IK, Komponens alapú szoftverfejlesztés 9:3
Adatok állapotai
record statesession statedisplay state
Grafikus felületű alkalmazások architektúrái
• Az állapotok külön általában reprezentációt igényelnek, ezért az
állapotok között transzformációkat kell végeznünk
• pl. objektumok közötti leképezés (object-object mapping),
objektum-relációs leképezés (object-relational mapping)
• Az egyes állapotok kezelése történhet
• szinkron módon: a két állapot mindig megegyezik
• a megjelenített és munkafolyamat állapotnak célszerű
megegyeznie, mivel a munkafolyamat állapoton hajtjuk végre
a tevékenységeket
• aszinkron módon: a két állapot általában különbözik, de adott
ponton szinkronizálható
ELTE IK, Komponens alapú szoftverfejlesztés 9:4
Adatok állapotai
Grafikus felületű alkalmazások architektúrái
• A háromrétegű architektúrában a felhasználóval a nézet réteg tartja a
kapcsolatot, amely ezért tartalmazza a felületi logikát (UI logic)
• a felületi logika feladatai:
• felhasználói interakció fogadása, feldolgozása, és továbbítása
az üzleti logika számára
• az adatok megjelenítése (a megjelentéshez szükséges
konverzióval)
• a megfelelő nézet előállítása, új nézetek létrehozása
• a felületi logika és maga a megjelenítés két jól elhatárolható
feladatkör, amelyet célszerű szeparálni
• a megjelenítés elsősorban nem programozói, hanem tervezői
feladatkör
ELTE IK, Komponens alapú szoftverfejlesztés 9:5
Háromrétegű architektúra specializációja
Grafikus felületű alkalmazások architektúrái
• A Model-View-Presenter (MVP) architektúra lehetőséget ad a felületi
logika leválasztására egy prezentáció (presenter) számára
• a nézet felel az adatok megjelenítéséért (nézetállapot
előállításáért), valamint a felhasználó interakció fogadásáért, és
továbbításáért a prezentáció számára
• a prezentáció tartalmazza a felhasználói interakció
feldolgozásáért felelős tevékenységeket, úgymint
• továbbítja a kéréseket az üzleti logika számára
• megadja az interakcióra válaszoló nézetet
• a prezentáció ismeri a nézetet, a nézet azonban nem ismeri a
prezentációt
ELTE IK, Komponens alapú szoftverfejlesztés 9:6
MVP architektúra
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:7
MVP architektúra
MVP
nézet
modell
prezentáció
végrehajtás
felhasználó
jelzésfrissítés
Grafikus felületű alkalmazások architektúrái
• Az MVP architektúra két esete különböztethető meg:
• Supervising contoller (SC): a nézet ismeri a modellt (le tudja
kérni a munkafolyamat állapotot), és el tud végezni alapvető
tevékenységeket
ELTE IK, Komponens alapú szoftverfejlesztés 9:8
MVP architektúra (supervising controller)
Presenter
«event handler»
- HandleComplexEvent()
View
+ UpdateViewState() :void
- Convert(SessionState) :DisplayState
«event»
+ ComplexEvent()
«event handler»
- HandleViewEvent()
Model
1..*
1..*
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:9
MVP architektúra (supervising controller)
user
View Presenter Model
Click()
ViewEvent()
HandleEvent()
UpdateViewState()
GetState() :SessionState
Convert(SessionState) :
DisplayState
Grafikus felületű alkalmazások architektúrái
• Passive View (PV): a nézet nem ismeri a modellt, így a
prezentáció adja át a nézet számára a munkafolyamat állapotot
• szinte minden tevékenységet a prezentáció végez
• a nézet elsősorban grafikus vezérlők halmazának tekinthető
ELTE IK, Komponens alapú szoftverfejlesztés 9:10
MVP architektúra (passive view)
Presenter
- HandleViewEvent()
View
+ UpdateViewState(SessionState)
- Convert(SessionState) :DisplayState
«event»
+ ViewEvent()
Model
1..*
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:11
MVP architektúra (passive view)
user
View Presenter Model
Viewalt
[requires new view]
Click()
ViewEvent()
HandleEvent()
GetState() :SessionState
UpdateViewState(SessionState)
Convert(SessionState) :
DisplayState
UpdateViewState(SessionState)
Convert(SessionState) :
DisplayState
Grafikus felületű alkalmazások architektúrái
• Előnyei:
• a felületi logika leválasztható a nézetről, így a nézet ténylegesen
nem lép interakcióba az üzleti logikával
• a prezentáció a nézettől függetlenül tudja biztosítani új nézetek
létrehozását és a munkafolyamat állapot manipulálását
• a nézet független a prezentáció és a modell felületétől, így
tetszőlegesen változtatható
• a prezentáció és a nézet egymástól függetlenül tesztelhetőek
• Hátrányai:
• a nézet továbbra is tartalmaz kódot (eseménykezelők formájában)
• a megjelenített állapot frissítése manuálisan történik
ELTE IK, Komponens alapú szoftverfejlesztés 9:12
MVP architektúra
Grafikus felületű alkalmazások architektúrái
Feladat: Készítsünk egy táblajáték programot MVP SC
architektúrában, amelyben két játékos küzdhet egymás ellen.
• a korábbi nézet tevékenységeit felbontjuk a nézet
(IBoardGameView) és a prezentáció (BoardGamePresenter)
között
• a nézet interfésze egységes eseményeket definiál a játék
tevékenységeire (GameStarted, GameStepped, …),
valamint megadja a frissítés lehetőségét
(UpdateViewState)
• a nézet megvalósítása (DrawingForm) felel a tényleges
események átalakításáért játékbeli eseményekké
• a prezentáció kezeli a tevekénységeket, valamint a modell
összetett eseményeit (GameWon, GameOver)
ELTE IK, Komponens alapú szoftverfejlesztés 9:13
Példa
Grafikus felületű alkalmazások architektúrái
Tervezés:
ELTE IK, Komponens alapú szoftverfejlesztés 9:14
Példa
Presenter::BoardGamePresenter
- model :BoardGameModel
- view :IBoardGameView
- saveFileDialog :SaveFileDialog
- openFileDialog :OpenFileDialog
+ BoardGamePresenter(BoardGameModel)
- Model_GameWon(object, GameWonEventArgs) :void
- Model_GameOver(object, EventArgs) :void
- View_GameStarted(object, EventArgs) :void
- View_GameStepped(object, BoardEventArgs) :void
- View_LoadGame(object, EventArgs) :void
- View_SaveGame(object, EventArgs) :void
«property»
+ View() :IBoardGameView
«interface»
View::IBoardGameView
+ UpdateViewState() :void
«event»
+ GameStarted() :EventHandler<EventArgs>
+ GameStepped() :EventHandler<BoardEventArgs>
+ SaveGame() :EventHandler
+ LoadGame() :EventHandler
«property»
+ Model() :BoardGameModel
Form
View::DrawingForm
- model :BoardGameModel
+ DrawingForm()
+ UpdateViewState() :void
- Panel_Paint(object, PaintEventArgs) :void
- Panel_MouseDown(object, MouseEventArgs) :void
- TicTacToeForm_Resize(object, EventArgs) :void
- TicTacToeForm_KeyDown(object, KeyEventArgs) :void
- Model_FieldChanged(object, FieldChangedEventArgs) :void
+ OnGameStarted() :void
+ OnGameStepped(Int32, Int32) :void
+ OnSaveGame() :void
+ OnLoadGame() :void
«event»
+ GameStarted() :EventHandler<EventArgs>
+ GameStepped() :EventHandler<BoardEventArgs>
+ SaveGame() :EventHandler
+ LoadGame() :EventHandler
«property»
+ Model() :BoardGameModel
-view
Grafikus felületű alkalmazások architektúrái
Feladat: Készítsünk egy táblajáték programot MVP PV
architektúrában, amelyben két játékos küzdhet egymás ellen.
• a nézet (IBoardGameView) nem látja közvetlenül a modellt, így
a prezentáció (BoardGamePresenter) kéri le a munkafolyamat
állapotát (GetSessionState), és adja át a nézet számára
• a prezentáció veszi át a megmaradt modellbeli események
kezelését a nézettől (Model_FieldChanged)
ELTE IK, Komponens alapú szoftverfejlesztés 9:15
Példa
Grafikus felületű alkalmazások architektúrái
Tervezés:
ELTE IK, Komponens alapú szoftverfejlesztés 9:16
Példa
Presenter::BoardGamePresenter
- model :BoardGameModel
- view :IBoardGameView
- saveFileDialog :SaveFileDialog
- openFileDialog :OpenFileDialog
+ BoardGamePresenter(BoardGameModel)
- Model_GameWon(object, GameWonEventArgs) :void
- Model_GameOver(object, EventArgs) :void
- Model_FieldChanged(object, FieldChangedEventArgs) :void
- View_GameStarted(object, EventArgs) :void
- View_GameStepped(object, BoardEventArgs) :void
- View_LoadGame(object, EventArgs) :void
- View_SaveGame(object, EventArgs) :void
- GetSessionState() :PlayerData[]
«property»
+ View() :IBoardGameView
«interface»
View::IBoardGameView
+ UpdateViewState(PlayerData[,]) :void
«event»
+ GameStarted() :EventHandler<EventArgs>
+ GameStepped() :EventHandler<BoardEventArgs>
+ SaveGame() :EventHandler
+ LoadGame() :EventHandler
Form
View::DrawingForm
- sessionState :PlayerData ([,])
- boardWidth :Int32
- boardHeight :Int32
+ DrawingForm()
+ UpdateViewState(PlayerData[,]) :void
- Panel_Paint(object, PaintEventArgs) :void
- Panel_MouseDown(object, MouseEventArgs) :void
- TicTacToeForm_Resize(object, EventArgs) :void
- TicTacToeForm_KeyDown(object, KeyEventArgs) :void
+ OnGameStarted() :void
+ OnGameStepped(Int32, Int32) :void
+ OnSaveGame() :void
+ OnLoadGame() :void
«event»
+ GameStarted() :EventHandler<EventArgs>
+ GameStepped() :EventHandler<BoardEventArgs>
+ SaveGame() :EventHandler
+ LoadGame() :EventHandler
-view
Grafikus felületű alkalmazások architektúrái
• A Model-View-Controller (MVC) architektúra egy külön vezérlést
(contoller) biztosít, amely kiszolgálja a felhasználói kéréseket
• a vezérlő fogadja közvetlenül a kérést a felhasználótól,
feldolgozza azt (a modell segítségével), majd előállítja a
megfelelő (új) nézetet
• így a nézet mentesül a kérések fogadásától, átalakításától
• általában egy vezérlőhöz több nézet is tartozik
• a nézet a felület (jórészt deklaratív) meghatározása, amely
megjeleníti, szükség esetén átalakítja az adatokat
• elsősorban webes környezetben népszerű, mivel könnyen
leválasztható a nézet (HTML) a vezérléstől (URL)
ELTE IK, Komponens alapú szoftverfejlesztés 9:17
MVC architektúra
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:18
MVC architektúra
MVC
nézet
modell
vezérlő
végrehajtás
felhasználó
tevékenység frissítés
Grafikus felületű alkalmazások architektúrái
• Az MVC architektúra két esete különböztethető meg:
• lehívás alapú (pull-based): ismeri a modellt, az adatokat a
modelltől kéri le
• betöltés alapú (push-based): a vezérlő adja át a nézetnek a
megjelenítendő adatokat (ez a nézet modellje, vagy view model)
• Előnye:
• a nézetnek nem kell foglalkoznia az események feldolgozásával,
mivel azokat közvetlenül a vezérlő kapja meg
• Hátránya:
• a nézet továbbra is felel az adatok megfelelő átalakításáért, tehát
tartalmaz valamennyi logikát
ELTE IK, Komponens alapú szoftverfejlesztés 9:19
MVC architektúra
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:20
MVC architektúra (betöltés alapú)
Controller
View
user
Model
Event()
HandleEvent()
GetState() :SessionState
UpdateViewState(SessionState)Convert(SessionState) :
DisplayState
Grafikus felületű alkalmazások architektúrái
Feladat: Készítsünk egy táblajáték programot MVC architektúrában,
amelyben két játékos küzdhet egymás ellen.
• a vezérlő (BoardGameController) látja a modellt, illetve
létrehozza a nézetet, és kezeli a nézet eseményeit (billentyűzet
lenyomás, átméretezés, táblakattintás)
• a nézet interfészét kibővítjük a táblával kapcsolatos
információkkal (BoardWidth, BoardHeight)
• a táblakattintás (BoardClicked) egy összetett esemény, amelyet
a nézetben váltunk ki
• betöltés alapú megközelítést alkalmazunk, így továbbra is a nézet
feladata az állapotfrissítés (UpdateViewState) a kapott nézet
modell alapján
ELTE IK, Komponens alapú szoftverfejlesztés 9:21
Példa
Grafikus felületű alkalmazások architektúrái
Tervezés:
ELTE IK, Komponens alapú szoftverfejlesztés 9:22
Példa
Controller::BoardGameController
- model :BoardGameModel
- view :BoardGameView
- saveFileDialog :SaveFileDialog
- openFileDialog :OpenFileDialog
+ BoardGameController(BoardGameModel)
- Model_GameWon(object, GameWonEventArgs) :void
- Model_GameOver(object, EventArgs) :void
- Model_FieldChanged(object, FieldChangedEventArgs) :void
- View_Shown(object, EventArgs) :void
- View_BoardClicked(object, BoardEventArgs) :void
- View_KeyDown(object, KeyEventArgs) :void
- View_Resize(object, EventArgs) :void
- LoadGame() :void
- SaveGame() :void
- GetSessionState() :PlayerData[]
«property»
+ View() :BoardGameView
Model::BoardGameModel
Form
View::BoardGameView
+ UpdateViewState(PlayerData[,]) :void
# OnBoardClicked(Int32, Int32) :void
«property»
+ BoardWidth() :Int32
+ BoardHeight() :Int32
«event»
+ BoardClicked() :EventHandler<BoardEventArgs>
View::DrawingForm
-view
-model
Grafikus felületű alkalmazások architektúrái
• Az állapotok automatikus szinkronizálását adatkötés (data binding)
segítségével érhetjük el, amely két lehetséges módon biztosíthatja a
szinkronizációt
• az érték módosítás hatására átíródhat a másik állapotba
• az érték módosítás hatására jelzést adhat a másik állapot
frissítésére
ELTE IK, Komponens alapú szoftverfejlesztés 9:23
Adatkötés
megjelenített
állapot
munkafolyamat
állapot
módosításmódosítás
megjelenített
állapot
munkafolyamat
állapotállapotlekérés
változásjelzésmódosítás
Grafikus felületű alkalmazások architektúrái
• Az adatkötésért egy olyan adatkötés objektum (Binding) felel,
amelyet a megjelenített állapot tárolója (nézet) és a munkafolyamat
állapot tárolója (modell) közé helyezünk
• az adatkötés ismeri mind a nézetet mind a modellt, ezért
lehívhatja az értékeket (GetState), és elvégezheti a módosítást
(SetState)
• elvégezheti az átalakítást (Convert) a munkafolyamat állapot és
a nézet állapot között
• általában minden szinkronizálandó adathoz külön adatkötés
tartozik, többszörös előfordulás esetén akár előfordulásonként is
tartozhat adatkötés
• a nézet ismerheti az adatkötést, így közvetlenül kezdeményezheti
a módosítást az adatkötésen keresztül
ELTE IK, Komponens alapú szoftverfejlesztés 9:24
Adatkötés
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:25
Adatkötés (modell irányába)
client
View Binding Controller
Button_Clicked()
SetState(DisplayState) Convert(DisplayState) :
SessionState
SetState(SessionState)
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:26
Adatkötés (nézet irányába)
View Binding Contoller
SetState(s : SessionState)
Convert(s : SessionState) :
DisplayState
SetState(DisplayState)
Grafikus felületű alkalmazások architektúrái
• Az adatkötés nyelvi támogatásként érhető el modern .NET
platformokon (pl. WPF, WinRT, UWP, Xamarin)
• a grafikus felületet deklaratívan, XAML segítségével írjuk le
• a felületen a kötéseket a Binding típus segítségével adjuk meg a
cél helyén, és megadjuk a forrást (Source), továbbá
megadhatjuk az átalakítás módját (Converter), pl.:
<Label Text="{Binding Source=Value}" />
<!-- a feliratot adatkötéssel adjuk meg -->
• magára a teljes felületre az adatforrást (a nézet modellt) a
DataContext tulajdonság segítségével helyezhetjük, pl.:
ViewModel vm = new ViewModel; // nézet modell
vm.Value = 0; // érték beállítása
view.DataContext = vm; // adatforrás megadása
ELTE IK, Komponens alapú szoftverfejlesztés 9:27
Adatkötés megvalósítása
Grafikus felületű alkalmazások architektúrái
• A parancs (command) tervminta célja egy művelet kiemelése egy
külön objektumba, így azt több objektum többféleképpen is igénybe
veheti
• a végrehajtandó tevékenység (Action) formája, paraméterezése
tetszőleges lehet, ezért nem lehet egyazon módon különböző
környezetekben kezelni
• a parancs (Command) egy egységes formát biztosít egy
tevékenység végrehajtására (Execute), a konkrét parancs
(ConcreteCommand) pedig biztosítja a megfelelő tevékenység
végrehajtását
• a kezdeményező (Invoker) csupán a parancsot látja, így a
tényleges végrehajtás előle rejtett marad
ELTE IK, Komponens alapú szoftverfejlesztés 9:28
Parancsok
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:29
Parancsok
Client
Invoker
«interface»
Command
+ Execute()
Receiver
+ Action()ConcreteCommand
- state
+ Execute()
receiver.Action()
-receiver
Grafikus felületű alkalmazások architektúrái
• A parancsok nyelvi támogatásként érhetőek el modern .NET
platformokon (pl. WPF, WinRT, UWP, Xamarin)
• a parancs (ICommand) lehetőséget ad egy tetszőleges
tevékenység végrehajtására (Execute), illetve a
végrehajthatóság ellenőrzésére (CanExecute)
• célszerű a tevékenységeket lambda-kifejezések (Action)
formájában megvalósítani
• a parancsokat adatkötés segítségével, a nézet modellen keresztül
kapcsolhatjuk a grafikus felületre, ahol a vezérlők parancs
(Command) tulajdonságához köthetjük, pl.:
<Button … Command="{Binding MyCommand}" />
<!-- a parancsot adatkötéssel adjuk meg -->
ELTE IK, Komponens alapú szoftverfejlesztés 9:30
Parancsok megvalósítása
Grafikus felületű alkalmazások architektúrái
• A Model-View-Viewmodel (MVVM), vagy prezentációs modell (PM)
architektúra a nézettel kapcsolatos tevékenységeket, illetve a
nézetállapot frissítését egy nézetmodell (viewmodel) komponensbe
helyezi
• a nézetmodell tartalmazza a felületi adatokat (megjelenített
állapot), valamint a tevékenységek végrehajtásához szükséges
műveleteket (parancsok formájában)
• a nézethez a megjelenített állapotot adatkötéssel kapcsoljuk, a
nézetmodell pedig automatikusan jelez a nézetállapot
megváltozásáról (figyelő segítségével)
• Az összetett tevékenységeket (pl. nézetek létrehozása) egy külön
alkalmazás vezérlés (application control) biztosítja
ELTE IK, Komponens alapú szoftverfejlesztés 9:31
MVVM architektúra
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:32
MVVM architektúra
MVVM
nézet
modell
nézetmodell
végrehajtás
felhasználó
adatkötésjelzés
alkalmazás
vezérlés
jelzés
létrehozás
Grafikus felületű alkalmazások architektúrái
• A figyelő (observer) tervminta célja összefüggőség megadása az
objektumok között, hogy egyik állapotváltozása esetén a többiek
értesítve lesznek
• a figyelő (Observer) ehhez biztosítja a változás jelzésének
metódusát (Update)
• a megfigyelt objektumok (Subject) az értékeikben tett
változtatásokat jelzik a felügyelőknek (Notify)
• egy objektumot több figyelő is nyomon kísérhet
• az MVVM architektúrában a figyelő szerepét az adatkötés tölti
be, míg a megfigyelt objektum a nézetmodell
ELTE IK, Komponens alapú szoftverfejlesztés 9:33
Figyelő
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:34
Figyelő
Subject
- observers :List<Observer>
+ Attach(Observer)
+ Detach(Observer) :Observer
+ Notify()
for (all o in observers)
o.Update()
Observer
+ Update()
ConcreteSubject
- subjectState
+ GetState()
return subjectState
+ SetState(State)
Notify()
ConcreteObserver
- observerState
+ Update()
observerState =
subject.GetState()
-observers
1..*
-subject
Grafikus felületű alkalmazások architektúrái
• A nézetmodell tekinthető egy átjárónak (proxy), amely a nézet és a
modell között helyezkedik el
ELTE IK, Komponens alapú szoftverfejlesztés 9:35
MVVM architektúra
Application
Control View
ViewModel
+ HandleEvent()
- Convert(Value) :DisplayedValue
+ GetState() :DisplayedValue
«event»
+ Notify()
+ ComplexEvent()
Model
Command
+ Execute()
*
*
*
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:36
MVVM architektúra
client
View Command ViewModel Model
Execute(Value)
HandleEvent()
GetState() :SessionState
Convert(SessionState) :
DisplayedStateNotify()
GetState() :DisplayedState
Grafikus felületű alkalmazások architektúrái
• Előnyei:
• a nézet csak a felület deklaratív leírását tartalmazza, minden
tevékenység és adatkezelés (átalakítás) külön rétegben található
• a felület teljesen függetlenül alakítható ki a nézetmodelltől
• Hátrányai:
• összetett architektúra, alapos átgondolást, és sok beépített elemet
igényel
• a nézet és a nézetmodell összekötése közötti inkonzisztenciák
csak futási időben derülnek ki
ELTE IK, Komponens alapú szoftverfejlesztés 9:37
MVVM architektúra
Grafikus felületű alkalmazások architektúrái
• Az MVVM architektúra megvalósítása nyelvi támogatásként érhető
el modern .NET platformokon (pl. WPF, WinRT, UWP, Xamarin)
• használjunk az adatkötést (Binding) és a parancsokat
(ICommand)
• az adatokban (tulajdonságokban) történt változások nyomon
követése a nézetmodellben történik
(INotifyPropertyChanged)
• a megadott tulajdonság módosításakor kiválthatjuk a
NotifyPropertyChanged eseményt
• gyűjteményekben bekövetkezett változásokat is nyomon
követhetünk (INotifyCollectionChanged)
ELTE IK, Komponens alapú szoftverfejlesztés 9:38
MVVM architektúra megvalósítása
Grafikus felületű alkalmazások architektúrái
ELTE IK, Komponens alapú szoftverfejlesztés 9:39
MVVM architektúra megvalósítása
View
ViewModel
Model
«interface»
INotifyPropertyChanged
«event»
+ PropertyChanged() :PropertyChangedEventHandler
FrameworkElement
ViewModelCommand
«interface»
ICommand
+ CanExecute(Object) :bool
+ Execute(Object) :void
ViewModelItem
ObservableCollection
+DataContext
Binding
*
Binding
*
*
Grafikus felületű alkalmazások architektúrái
Feladat: Készítsünk egy táblajáték programot MVVM architektúrában,
amelyben két játékos küzdhet egymás ellen.
• külön projektet hozunk létre a nézetmodellnek (ViewModel),
valamint a nézetnek (View.Presentation)
• kiegészítjük a nézetmodellt a változásjelzéssel
(INotifyPropertyChanged), amelyet egy közös ősosztályban
kezelünk, és váltunk ki (ViewModelBase)
• a tevékenységeket felbontjuk a nézetmodell és az alkalmazás
(App) között
• új nézetet igénylő tevékenységekről (pl. betöltés, mentés,
játék vége) a nézetmodell, vagy a modell eseményt küld az
alkalmazásnak
ELTE IK, Komponens alapú szoftverfejlesztés 9:40
Példa
Grafikus felületű alkalmazások architektúrái
Tervezés:
ELTE IK, Komponens alapú szoftverfejlesztés 9:41
Példa
Application
App
- persistence :IPersistence
- model :BoardGameModel
- viewModel :BoardViewModel
- window :BoardGameWindow
- openFileDialog :OpenFileDialog
- saveFileDialog :SaveFileDialog
+ App()
- App_Startup(object, StartupEventArgs) :void
- Model_GameWon(object, GameWonEventArgs) :void
- Model_GameOver(object, EventArgs) :void
- ViewModel_LoadGame(object, System.EventArgs) :void
- ViewModel_SaveGame(object, System.EventArgs) :void
- ViewModel_GameExit(object, System.EventArgs) :void
Window
View::BoardGameWindow
+ BoardGameWindow()ViewModelBase
ViewModel::BoardItemViewModel
- player :String
+ BoardItemViewModel(Action<Object>)
«property»
+ Column() :Int32
+ Row() :Int32
+ Number() :Int32
+ Player() :String
+ BoardItemCommand() :DelegateCommand
ViewModelBase
ViewModel::BoardViewModel
- model :BoardGameModel
+ BoardViewModel(BoardGameModel)
- NewGame() :void
- GetDisplayedState(PlayerData) :String
- CreateBoard() :void
- Model_FieldChanged(object, FieldChangedEventArgs) :void
- OnLoadGame() :void
- OnSaveGame() :void
- OnGameExit() :void
«event»
+ GameExit() :EventHandler
+ LoadGame() :EventHandler
+ SaveGame() :EventHandler
«property»
+ NewGameCommand() :DelegateCommand
+ LoadGameCommand() :DelegateCommand
+ SaveGameCommand() :DelegateCommand
+ ExitGameCommand() :DelegateCommand
+ BoardWidth() :Int32
+ BoardHeight() :Int32
+ BoardItems() :ObservableCollection<BoardItemViewModel>
Model::BoardGameModel-model
*
-window
-viewModel
-model
top related