bsc thesis - simplexpense

70
Budapesti Műszaki és Gazdaságtudományi Egyetem 1117 Budapest, Magyar tudósok körútja 2. Q épület, B szárny, II. em. 207. Villamosmérnöki és Informatikai Kar Telefon: +36/1/463-2870, +36/1/463-3716 Fax: +36/1/463-2871 Automatizálási és Alkalmazott Informatikai Tanszék http:/www.aut.bme.hu, H-1521 Budapest SZAKDOLGOZAT FELADAT Trajber Barna Viktor szigorló mérnökinformatikus hallgató részére Költségnyilvántartó keretrendszer .NET alapon Amikor egy háztartás, vagy kisvállalat költségvetését szeretnénk nyilvántartani, kézenfekvő, hogy elektronikusan tároljuk a kiadásokat és bevételeket, a számlabefizetéseket. Ez lehetővé teszi az egyszerű, biztonságos tárolást, a könnyű adatbevitelt, különböző szűrések és rendezések eredményeinek megtekintését. A szakdolgozat célja egy kiadás nyilvántartó alkalmazáscsalád fejlesztése, melyet a költségkategóriák testreszabásával akár otthoni, illetve kisvállalati környezetben is használhatunk. Az elkészült keretrendszernek tartalmaznia kell egy szerver oldali alkalmazást, melynek elsődleges feladata, hogy kommunikáljon a különböző platformokon megvalósított kliens alkalmazásokkal. A hallgató feladatának a következőkre kell kiterjednie: Tervezze meg a keretrendszer felépítését és adatbázis sémáját! Készítsen egy szerveralkalmazást, amely WCF szolgáltatást nyújt a kliensek felé! Készítsen egy mobil kliens alkalmazást Windows Phone 8 platformra! Készítsen egy vékony kliens alkalmazást ASP.NET MVC keretrendszer segítségével! Tanszéki konzulens: Dr. Asztalos Márk Budapest, 2013. október 10. Dr. Vajk István egyetemi tanár tanszékvezető

Upload: barna-trajber

Post on 12-Apr-2017

137 views

Category:

Software


2 download

TRANSCRIPT

Page 1: BSc Thesis - SimpleXpense

Budapesti Műszaki és Gazdaságtudományi Egyetem 1117 Budapest, Magyar tudósok körútja 2. Q épület, B szárny, II. em. 207.

Villamosmérnöki és Informatikai Kar Telefon: +36/1/463-2870, +36/1/463-3716 Fax: +36/1/463-2871

Automatizálási és Alkalmazott Informatikai Tanszék http:/www.aut.bme.hu, H-1521 Budapest

SZAKDOLGOZAT FELADAT

Trajber Barna Viktor

szigorló mérnökinformatikus hallgató részére

Költségnyilvántartó keretrendszer .NET alapon

Amikor egy háztartás, vagy kisvállalat költségvetését szeretnénk nyilvántartani,

kézenfekvő, hogy elektronikusan tároljuk a kiadásokat és bevételeket, a

számlabefizetéseket. Ez lehetővé teszi az egyszerű, biztonságos tárolást, a könnyű

adatbevitelt, különböző szűrések és rendezések eredményeinek megtekintését.

A szakdolgozat célja egy kiadás nyilvántartó alkalmazáscsalád fejlesztése, melyet

a költségkategóriák testreszabásával akár otthoni, illetve kisvállalati környezetben is

használhatunk. Az elkészült keretrendszernek tartalmaznia kell egy szerver oldali

alkalmazást, melynek elsődleges feladata, hogy kommunikáljon a különböző

platformokon megvalósított kliens alkalmazásokkal.

A hallgató feladatának a következőkre kell kiterjednie:

Tervezze meg a keretrendszer felépítését és adatbázis sémáját!

Készítsen egy szerveralkalmazást, amely WCF szolgáltatást nyújt a kliensek felé!

Készítsen egy mobil kliens alkalmazást Windows Phone 8 platformra!

Készítsen egy vékony kliens alkalmazást ASP.NET MVC keretrendszer

segítségével!

Tanszéki konzulens: Dr. Asztalos Márk

Budapest, 2013. október 10.

Dr. Vajk István

egyetemi tanár

tanszékvezető

Page 2: BSc Thesis - SimpleXpense

2

Budapesti Műszaki és Gazdaságtudományi Egyetem

Villamosmérnöki és Informatikai Kar

Automatizálási és Alkalmazott Informatikai Tanszék

Trajber Barna Viktor

KÖLTSÉGNYILVÁNTARTÓ

KERETRENDSZER .NET ALAPON

KONZULENS

Dr. Asztalos Márk

BUDAPEST, 2014

Page 3: BSc Thesis - SimpleXpense

Tartalomjegyzék

Összefoglaló ..................................................................................................................... 6

Abstract ............................................................................................................................ 7

1 Bevezetés ....................................................................................................................... 8

2 Technológiai ismertető .............................................................................................. 10

2.1 ASP.NET MVC 4 ................................................................................................. 10

2.1.1 ASP.NET architektúra ................................................................................... 10

2.1.2 MVC architektúra .......................................................................................... 11

2.1.3 Az oldal életciklusa ........................................................................................ 16

2.1.4 MVC és WebForms összehasonlítása ............................................................ 16

2.2 Vizuális komponensek .......................................................................................... 19

2.2.1 Twitter Bootstrap ........................................................................................... 19

2.2.2 Telerik Kendo UI ........................................................................................... 20

2.3 Windows Phone 8 ................................................................................................. 22

2.3.1 Felület ............................................................................................................ 22

2.3.2 Az alkalmazás életciklusa .............................................................................. 23

2.3.3 Hardver követelmények ................................................................................. 24

2.3.4 Fejlesztés Windows Phone 8 platformra ....................................................... 24

2.4 WCF ...................................................................................................................... 30

2.4.1 WCF architektúra és fogalmak ...................................................................... 30

2.4.2 Üzenetcsere minták ........................................................................................ 30

2.4.3 Végpontok ...................................................................................................... 30

2.4.4 WCF és WebAPI összehasonlítása ................................................................ 33

3 Specifikáció ................................................................................................................. 35

3.1 Szoftver célja ........................................................................................................ 35

3.2 Funkciók ............................................................................................................... 36

3.3 Felhasználói szerepkörök ...................................................................................... 37

3.4 Architektúra .......................................................................................................... 38

4 Megvalósítás ............................................................................................................... 40

4.1 Adatbázis tervezése ............................................................................................... 40

4.1.1 Code First vagy Database First? .................................................................... 40

4.1.2 Az adatbázis séma .......................................................................................... 41

Page 4: BSc Thesis - SimpleXpense

4.1.3 Táblák és attribútumok .................................................................................. 43

4.1.4 Megjegyzések az adatmodellhez ................................................................... 44

4.2 Szerver és a szolgáltatás ....................................................................................... 45

4.2.1 Üzleti logika ................................................................................................... 45

4.3 Kliens alkalmazások ............................................................................................. 51

4.3.1 Mobil kliens (WP8) ....................................................................................... 51

4.3.2 Web kliens (ASP.NET MVC) ....................................................................... 58

5 Összefoglalás ............................................................................................................... 65

5.1 Továbbfejlesztési lehetőségek .............................................................................. 66

Irodalomjegyzék ............................................................................................................ 67

Függelék: Kliensek egyéb funkciói .............................................................................. 69

Page 5: BSc Thesis - SimpleXpense

HALLGATÓI NYILATKOZAT

Alulírott Trajber Barna Viktor, szigorló hallgató kijelentem, hogy ezt a szakdolgozatot

meg nem engedett segítség nélkül, saját magam készítettem, csak a megadott forrásokat

(szakirodalom, eszközök stb.) használtam fel. Minden olyan részt, melyet szó szerint,

vagy azonos értelemben, de átfogalmazva más forrásból átvettem, egyértelműen, a forrás

megadásával megjelöltem.

Hozzájárulok, hogy a jelen munkám alapadatait (szerző(k), cím, angol és magyar nyelvű

tartalmi kivonat, készítés éve, konzulens(ek) neve) a BME VIK nyilvánosan hozzáférhető

elektronikus formában, a munka teljes szövegét pedig az egyetem belső hálózatán

keresztül (vagy hitelesített felhasználók számára) közzétegye. Kijelentem, hogy a

benyújtott munka és annak elektronikus verziója megegyezik. Dékáni engedéllyel

titkosított diplomatervek esetén a dolgozat szövege csak 3 év eltelte után válik

hozzáférhetővé.

Kelt: Budapest, 2014. 05. 15.

...…………………………………………….

Trajber Barna Viktor

Page 6: BSc Thesis - SimpleXpense

6

Összefoglaló

Az életünk részét képző gyakori pénzáramlások szinte lehetetlenné teszik, hogy

fejben tartsuk az összes felmerülő anyagi tételt. A különböző számlabefizetések,

vásárlások, váratlan kiadások vagy a fizetések és egyéb bevételi források nyilvántartása

közben könnyen elveszíthetjük a fonalat. Eljuthatunk arra a pontra, amikor azt érezzük,

hogy szükségszerű lenne egy helyen tárolni a költségeinket. Napjaink informatikai

megoldásai ezt könnyedén lehetővé teszik, akár széles körű platform támogatottság

mellett is.

Munkám során egy olyan költségnyilvántartó keretrendszert hoztam létre,

melyben a felmerülő kiadásokat és bevételeket hatékonyan kezelhetjük elektronikusan,

rendszerezetten tárolva és áttekinthető formában megjelenítve a különböző kimutatások

és szűrések segítségével. A költségkategóriák testreszabásával az igényeknek

megfelelően tudjuk kialakítani a rendszer profilját, lehetővé téve, hogy akár személyes

vagy kisvállalati környezetben is alkalmazható szoftverrel rendelkezzünk. A felhasználói

szintek bevezetése tette lehetővé, hogy csak az adminisztrátorok legyenek képesek

beavatkozni a kategóriák kezelésébe, így az egyszerű felhasználóknak csupán a

költségeik nyilvántartásával kell foglalkozniuk.

A keretrendszer .NET alapokon nyugszik, szolgáltatás-orientált (SOA)

architektúrát valósítva meg. A rendszer magját egy WCF szolgáltatás adja, mely

elérhetővé teszi az üzleti logikát a kliensek számára, gondoskodva az adatok

feldolgozásáról és tárolásáról is. Az implementáció során két kliens alkalmazás készült el

különböző platformokra: egy vékony kliens az ASP.NET MVC keretrendszerre építve,

melynek a felületét a Twitter Bootstrap és Telerik Kendo UI csomagok segítségével

készítettem el, illetve egy Windows Phone 8 alapú mobil klienst is fejlesztettem.

A rendszer egyszerűen bővíthető újabb kliens alkalmazások hozzáadásával,

hiszen a szolgáltatással összeköttetésben állva a klienseknek csupán a megfelelő

felhasználói felületet és a platform specifikus részeket kell megvalósítaniuk.

Page 7: BSc Thesis - SimpleXpense

7

Abstract

Cash flows form an important part of our lives but it is almost impossible to keep

in mind all the financial items that arise. You can easily lose the thread between different

kinds of bill payments, purchases, unexpected expenses or salaries. We may get to the

point when we feel that it is necessary to find a reliable place to store the costs. Today's

IT solutions allow us to make these tasks easy even with a wide range of platform support.

In my work I have created an expense manager framework that can efficiently

manage the expenses and incomes electronically in a systematic way and allow us to

browse the items using various reports and filters. We can determine the system profile

by the customization of the cost categories according to our needs, allowing this software

to be used either for personal purposes or in a small business environment. The

introduction of user roles made it possible that only administrators are able to take part in

the handling of categories so the basic users have to deal only with their costs

management.

The constructed framework presented in this thesis is based on .NET and it

implements a service-oriented architecture (SOA). The core of the system is a WCF

service that provides access to the business logic for the clients, ensuring the processing

and storage of data as well. I have created two different client applications: a web client

based on ASP.NET MVC extended by Twitter Bootstrap and Telerik Kendo UI packages,

and a mobile client for Windows Phone 8 platform was also developed.

The system can be easily extended by adding new client applications that are

connected to the service so we only need to develop the appropriate user interface and

platform specific parts.

Page 8: BSc Thesis - SimpleXpense

8

1 Bevezetés

Egy háztartásban figyelemmel követni a havi bevételeteket, illetve kiadásokat már

rövid távon is meglehetősen összetett feladattá válhat. A probléma támogatásához precíz,

ugyanakkor egyszerűen kezelhető elektronikus keretrendszer fejlesztése úgy gondolom,

hogy indokolt és kihívást jelentő feladat.

A szakdolgozatom témája egy olyan költségnyilvántartó keretrendszer

létrehozása volt, melyben áttekinthető képet kaphatunk a napi költségekről és

bevételekről a különböző szűrések, kimutatások segítségével. A költség kategóriák

testreszabásával otthoni és kisvállalati környezetben is egyaránt használható alkalmazást

kellet létrehoznom. A rendszerben tehát szükséges a felhasználói szintek

megkülönböztetése, hogy az adminisztrátor az igényeknek megfelelően testre tudja

szabni a nyilvántartandó kiadások és bevételek kategóriáit, ezzel biztosítva a minél

teljesebb körű felhasználhatóságot. A rendszer felhasználói pedig élvezhetik a

keretrendszer nyújtotta kényelmet, melyben hatékonyan el tudják tárolni a felmerülő

anyagi tételeket.

Napjainkban minden szükséges technikai eszköz adott egy valóban jól

használható költségnyilvántartó szoftver megalkotásához. Az „okostelefonok” növekvő

népszerűségével költségeinket akár kézben is tarthatjuk. A célom egy olyan

bonyolultságú keretrendszert készíteni, mely egyszerre asztali, mobil, valamint webes

környezetben is megállja a helyét, könnyedén bővíthető újabb kliens alkalmazásokkal,

ezáltal szélesebb felhasználói közönséget célozva meg.

A tervezés során kiemelt hangsúlyt fektettem arra, hogy egy olyan keretrendszert

valósítsak meg, mely stabil, megbízható alapot nyújt az esetleges későbbi funkcionális

bővítések számára, egyszerűen használható és teljes értékű funkcionalitás nyújt az összes

kliens platformra. A fejlesztéshez plusz motivációt adott, hogy lehetőségem volt

alaposabban megismerkedni különböző .NET-es technológiákkal, hasznos csomagokkal

és osztálykönyvtárakkal.

Page 9: BSc Thesis - SimpleXpense

9

A következő fejezetben egy technológiai ismertető keretében rövid áttekintést

kaphatunk a keretrendszer elkészítése során felhasznált technológiákról és eszközökről,

helyenként összehasonlítva alternatív .NET-es megoldásokkal. Először a vékonykliens

alapjául szolgáló ASP.NET MVC [1] keretrendszert mutatom be, majd az ehhez

kapcsolódóan felhasznált Twitter Bootstrap [12] és Telerik Kendo UI [14] vizuális

csomagokat ismertetem. A további részekben szót ejtek a Windows Phone 8 [15] mobil

platformról, melyre a mobil kliens alkalmazás készült; legutoljára pedig az üzleti logikát

biztosító WCF (Windows Communication Foundation) [29] szolgáltatás technológiájával

ismerkedhetünk meg.

A 3. fejezetben a rendszer specifikációját mutatom be. Először szó esik a szoftver

fejlesztése során kitűzött célokról, majd a feladat pontosítása érdekében a kötelezően

megvalósítandó funkciókat tekinthetjük át. Utolsó lépésként a felhasználói szinteket és a

rendszer architektúráját ismertetem.

A 4. fejezetben a megvalósított keretrendszer fejlesztésének néhány lépését

tekinthetjük át, melyben először az adatbázis tervezése során keletkezett adatmodellt

ismertetem. A további alfejezetekben a szolgáltatás üzleti logikáját és az egyes kliens

alkalmazások felépítését mutatom be az összetettebb implementációs részleteket

kiemelve. Mind a két elkészül kliens esetén a felhasználó kezelés ismertetésével kezdem,

majd pedig a platformra jellemző egyedi megoldásokat részletezem.

Az utolsó fejezetben összefoglalom a szakdolgozatomban elért eredményeket és

beszámolok a továbbfejlesztési lehetőségekről is.

Page 10: BSc Thesis - SimpleXpense

10

2 Technológiai ismertető

Első lépésként a szakdolgozatban használt lényegesebb technológiákat

ismertetem egy rövid áttekintés erejéig. Az itt szereplő technológiák a .NET világában

ismertek, így a célom, hogy néhány érdekesebb részletet kiemeljek.

Először a kliens alkalmazások fejlesztéséhez használt eszközöket mutatom be, így

szó esik az ASP.NET MVC [1] keretrendszerről mely a web alkalmazásom alapja. Ezt

követően a weboldal készítése során felhasznált vizuális komponenseket ismertetem.

Továbbiakban a Windows Phone 8 [15] mobil platformot is áttekinthetjük, melyre a

mobil klienst fejlesztettem, a felhasznált csomagokkal és osztálykönyvtárakkal együtt. A

kommunikáció megteremtéséhez a szolgáltatás és a kliens alkalmazások között a WCF

[29] technológiát használtam, így legutoljára ezzel ismerkedhetünk meg.

2.1 ASP.NET MVC 4

Az ASP.NET MVC 4 keretrendszer segítségével jól skálázható web

alkalmazásokat készíthetünk, az ASP.NET, illetve az egész .NET keretrendszer erejére

építve a bevált tervezési minták használatával.

2.1.1 ASP.NET architektúra

A keretrendszer alapját képző ASP.NET architektúráját az alábbi ábrán

tekinthetjük meg.

A technológia blokksémán

látható, hogy az egész MVC az

ASP.NET-re épül, hasonlóan a zöld

sávban levő többi technológiához. Az

ASP.NET alapvetően 4 különböző

web fejlesztési irányt kínál

számunkra: Single Page Apps (SPA)

[2] , Web Pages [3], MVC és a Web

Forms [4], kiegészítve 2 féle szolgáltatással: Web API [27] és a SignalR [6].

2-1. ábra: ASP.NET technológia blokkséma [7]

Page 11: BSc Thesis - SimpleXpense

11

A Single Page Applications (SPA) az interaktivitásra és felhasználói élmény

fokozására helyezi a hangsúlyt a kliens oldali szkriptek jelentősebb szerepvállalásával, a

HTML 5, CSS 3 és különböző JavaScript keretrendszerek használatával [2].

A Web Pages a Razor szintaxis erejét használja ki, hogy gyorsan fejleszthető,

könnyen járható utat biztosítson dinamikus web tartalmak előállítására a szerver oldali

kódok HTML-be ágyazásával [3].

A Web Forms használatával a már bevált fogd-és-vidd (drag-and-drop)

módszerrel, eseményvezérelten hozhatunk létre dinamikus oldalakat. A tervezői felület

és sok-sok vezérlő, valamint komponens segítségével gyorsan hozhatunk létre a

felhasználói felület által vezérelt oldalakat. A Web Forms-ról hamarosan több szó is esik

az MVC-vel való összehasonlítás során (2.1.4-es fejezetben).

A szolgáltatások közül a SignalR egy új osztálykönyvtár az ASP.NET fejlesztők

számára, mely segítségével egyszerűen fejleszthetünk valós idejű web alkalmazásokat.

Kétirányú kommunikációt tesz lehetővé a kliens és a szerver között, a szerverek tehát

azonnal tudják szolgáltatni a szükséges tartalmat, amint az elérhetővé válik. A

technológia a Web Socket-ekre épít, azonban a régebbi böngészők támogatása érdekében

képes egyéb technikákat is használni, további API-kat kínálva az összeköttetés

menedzselésére: kapcsolatok csoportosítása, kapcsolódási események és hitelesítés [6].

A WebAPI-ról a 2.4.4-es fejezetben olvashatunk bővebben, ahol összehasonlítom

a WCF nyújtotta szolgáltatással.

Az ASP.NET MVC keretrendszer nyílt forráskódú és rendkívül gyors ütemben

fejlődik. A szakdolgozatomban a 4-es verziót használtam, ugyanis ehhez volt csak Telerik

Kendo UI [14] támogatásom, azonban időközben már az 5-ös verzió is megjelent. A

Telerik Kendo UI egy fizetős kiegészítő csomag számtalan webes komponenst

tartalmazva, melyek használatával modern és látványos felhasználói felületeket

alakíthatunk ki (bővebben a 2.2.2 fejezetben).

2.1.2 MVC architektúra

Az ASP.NET MVC segít csökkenteni egy web alkalmazás komplexitását azzal,

hogy három rétegre különíti el az alkalmazást: Model (modell), View (nézet) és

Controller (vezérlő) részekre. Az MVC minta előnye, hogy a komponensei izoláltak, azaz

jól el vannak különítve egymástól. Minden lehetőségünk adott, hogy az alkalmazás

Page 12: BSc Thesis - SimpleXpense

12

felelősségi köreit jól elszeparáltan tudjuk implementálni (Separation of Concerns1) és

szakítsunk a régi, mindent egy helyre zsúfoló megoldásokkal. A tervezésben és később a

megvalósításban is nagy segítség lehet, ha kialakított egységek külön-külön tovább

tervezhetőek, esetleg önmagukban is kivitelezhetőek, lecserélhetők és tesztelhetők. [7]

2-2. ábra: Az ASP.NET MVC keretrendszer komponensei [5]

A továbbiakban az MVC architektúra résztvevőit ismertetem.

Model (modell)

Összetartozó adatok halmaza. A modell az adatspecifikációja annak a

kapcsolatnak, ami az MVC keretrendszer View és a Controller elemei között végbemegy.

Gyakran a modell objektumok az állapotukat adatbázisból nyerik és ott is tárolják. Kis

alkalmazásokban a modell gyakran csak fogalmilag létezik, nem pedig fizikailag.

Például, ha az alkalmazásunk az adatbázisból olvas ki adatokat és azt elküldi a nézet

számára mindenféle módosítás nélkül, akkor nincs szükség erre a köztes rétegre. [5]

Fontos, hogy a modell osztályban definiált tulajdonságok (propertyk) jól legyenek

elnevezve, ugyanis ha ebből az osztályból egy példány valamely nézetnek a modellje lesz,

akkor abból a felhasznált HTML helperek segítségével a generált HTML elemek

elnevezései (name) és azonosítói (id) a tulajdonságok neveiből fognak képződni. Tehát

egy név megválasztásánál nemcsak a .NET/CIL2 elnevezési szabályoknak kell

megfelelnünk, hanem a HTML attribútumokra is legyünk tekintettel. [7]

1 Separation of Concerns – Egy tervezési alapelv arra, hogy szétválasszunk a teljes forráskódot

különálló részekre, ahol minden egyes szekciónak meghatározott felelőssége van.

2 CIL (MSIL) – Common Intermediate Language. A legalacsonyabb szintű programozási nyelv a

.NET keretrendszerben és a Common Language Infrastructure-ben. Azok a nyelvek, melyek a .NET

keretrendszert használják, a CIL-re fordítanak, ami végül a kezelt kódra fordul.

Page 13: BSc Thesis - SimpleXpense

13

A modellünket bővíthetjük viselkedéssel is. Ide kerülhetnek olyan tulajdonságok,

melyek számított értékként funkcionálnak vagy attribútumokkal vannak dekorálva,

amivel szabályozzák a megjelenést. Az egyszerűbb üzleti logikát is megvalósíthatjuk a

modellben, kicsit felszabadítva ezzel a vezérlőt. Természetesen nagyobb rendszereknél,

komplex üzleti logika esetén kerülendő ez a megoldás, ilyenkor a kontrollerben vagy még

inkább egy szolgáltatásban érdemes megvalósítani az üzleti logikát.

Validáció (érvényesítés)

Az alábbi példa egy egyszerű modell osztály, ami validációs attribútumok

segítségével segít az adatérvényesítésben, illetve a megjelenést szabályozó attribútumok

segítségével formálja a generált HTML elemeket:

public class ChangePasswordModel { private const string validationErrorMessage = "{0} must be {2} to {1} characters long!"; // . . . Other properties [Required] [Display(Name = "New password")] [DataType(DataType.Password)] [StringLength(25, ErrorMessage = validationErrorMessage, MinimumLength = 3)] public string NewPassword { get; set; } [Required] [Display(Name = "New password again")] [Compare("NewPassword", ErrorMessage = "Passwords are not match")] [StringLength(25, ErrorMessage = validationErrorMessage, MinimumLength = 3)] public string PasswordAgain { get; set; } }

A Required attribútum segítségével jelezhetjük, hogy ez az érték kötelezően

kitöltendő egy HTML form elküldése esetén. A Display attribútum Name

tulajdonságának értéke a modellből generált HTML címke (<label>) szövege lesz. A

Compare segítségével két property mező tartalmát hasonlíthatjuk össze és csak akkor

érvényes a validáció, ha a kettő tulajdonság értéke megegyezik. A StringLength

használatával a szöveg maximális és minimális hosszát szabhatjuk meg. A DataType

attribútumok HTML 5 beviteli mezőtípusokat generálnak, aminek a validálása a

böngészőre van bízva. A valódi, MVC által kezelt validációs megoldásokat a DataType

attribútum leszármazottjai biztosítják (pl. EmailAddressAttribute,

PhoneAttribute, EnumDataTypeAttribute stb.).

Page 14: BSc Thesis - SimpleXpense

14

A validációs attribútumok listáját az alábbi táblázatban figyelhetjük meg:

Lehetőségek .NET 4.0 esetében További attribútumok .NET 4.5 alatt

ValidationAttribute

CompareAttribute (System.Web.Mvc)

CustomValidationAttribute

DataTypeAttribute

EnumDataTypeAttribute

RangeAttribute

RegularExpressionAttribute

RequiredAttribute

StringLengthAttribute

RemoteAttribute

ValidationAttribute

CompareAttribute (DataAnnotations)

MaxLengthAttribute

MinLengthAttribute

MembershipPasswordAttribute

DataTypeAttribute

CreditCardAttribute (+Microsoft.Web.Mvc)

EmailAddressAttribute (+Microsoft.Web.Mvc)

FileExtensionsAttribute (+Microsoft.Web.Mvc)

PhoneAttribute

UrlAttribute (+Microsoft.Web.Mvc)

1. táblázat: Validációs attribútumok a .NET-ben [7]

View (nézet)

A nézet felelős azért, hogy előállítsa a választ a böngésző számára, legyen az akár

egy HTML, pdf vagy excel dokumentum. Más megfogalmazásban mondhatjuk azt is,

hogy a nézet felelőssége, hogy a modell adatait megjeleníthető formára transzformálja

[9]. A View tulajdonképpen egy sablon (template) a válasz előállításához. A statikus

szakaszok HTML nyelvi elemekből épülnek fel, míg az „üres helyeket”, azaz a dinamikus

adatokat a Controller tölti ki a Model alapján. Alapértelmezetten két sablon nyelvet

(ViewEngine) is használhatunk a nézetek leírásához az MVC 3-as verziója óta, melyeket

azonban ki is terjeszthetünk [8]:

ASPX (.aspx): az ASP.NET WebForms hagyományos <% %> markerek közé zárt

szintaxisa, ami egy régi örökség:

<ul id="products"> <% foreach (var p in products) { %> <li><%=p.Name %> ($<%=p.Price %>)</li> <% } %> </ul>

Razor (.cshtml/.vbhtml): Jelenleg ez az ajánlott szintaxis az MVC-hez:

<ul id="products"> @foreach (var p in products) { <li>@p.Name ([email protected])</li> } </ul>

Megfigyelhető, hogy a Razor szintaxisa sokkal letisztultabb, kevesebb jelölőre

van szükség, és a kód blokk végét nem kell külön jelölni, ellentétben a ’<% %>’

szintaxissal. A web kliensem fejlesztése során a Razor-t használtam a nézetek leírására.

Page 15: BSc Thesis - SimpleXpense

15

Controller (vezérlő)

A vezérlő a böngésző felől érkező felhasználói kérések feldolgozását végzi, majd

az előállított választ visszaküldi valamely nézetnek. A vezérlő úgy működik, mint egy

koordinátor a nézet és a modell között, valójában az oldal generálás lelke [9].

Előfordulhat, hogy nincs modell definiálva, illetve olyan is, hogy View sem, de vezérlő

és action nélkül nem megy. Névkonvenció alapján dől el, hogy melyik View template

lesz az, ami sablonként fog szolgálni a dinamikus HTML tartalom előállításához. Ezen

az osztályok nevének hagyományosan Controller-el kell végződnie (pl.

AccountController) és a Controller ősosztályból öröklődnek. Az itt található

függvényeket, melyek az ActionResult ősből származó típussal térnek vissza, action-

öknek hívjuk és a feladatuk, hogy kiszolgáljanak egy-egy kérést.

Több lehetőségünk is van arra, hogy egy vezérlőhöz tartozó nézet számára

biztosítsuk az adatokat:

Modell: A legnyilvánvalóbb módja az adatok továbbításának. A Controller

ősosztályon levő View vagy PartialView metódus paramétereként átadhatjuk

kívánt modellt. A tárolási helye a ViewData-ban van.

HttpContext.Items[] gyűjtemény: Kulcs-érték párokat tároló dictionary.

Ideiglenes tárolási lehetőség, ami átível egy kérés feldolgozásának az életciklusán,

így már a global.asax-ban is használhatjuk. Nem MVC specifikus lehetőség, az

alap ASP.NET keretrendszer biztosítja ezt a gyűjteményt számunkra.

ViewData, ViewBag és a TempData: A ViewData egy szöveg (string, key) –

objektum (object, item) típusú dictionary, így az elemeit nem érhetjük el

típusosan, kénytelenek vagyunk az objektumot konvertálni. Tartalma a HTML

oldal generálása után elvész, azonban nem csak a vezérlőből, hanem a nézetekből

is elérhető a kérés feldolgozása során. A ViewBag a ViewData dinamikus

típusú párja (dynamic), ahol az egyes elemeket tulajdonságok formájában,

típusosan érhetjük el, így ennek a használata jóval kényelmesebb. A TempData a

ViewData-hoz hasonló dictionary, azonban a tartalma a teljes kérés feldolgozás

során elérhető, mert a Session objektumba van ágyazva.

Page 16: BSc Thesis - SimpleXpense

16

2.1.3 Az oldal életciklusa

Az MVC-nél az oldal életciklusát a böngészőből érkező kérés (request) indítja el.

A keretrendszer ezt a request-et egy vezérlőhöz juttatja (amit az URL-ből a route

konfigurációnak megfelelőn választ ki), annak is egy metódusához, azaz egy action-höz.

Ez a metódus létrehozza a modell példányt, ha szükséges, majd meghatározza, hogy a

modell alapján az MVC melyik View-t használja fel a böngészőnek küldendő válasz

létrehozásához. Az alábbi ábra vázlatosan szemlélteti egy böngésző felől érkező kérés

életciklusát az MVC keretrendszerben:

2-3. ábra: ASP.NET MVC kérésfeldolgozás vázlata [7]

2.1.4 MVC és WebForms összehasonlítása

Fontos megjegyezni, hogy míg a WebForms – a szintén Microsoft-os – Active

Server Pages (ASP) technológiát hivatott leváltani, addig az MVC nem a WebForms

leváltásaként jött létre, hanem egy újabb alternatívaként arra, hogy ASP.NET weboldalt

készítsünk.

A Web Forms alapötlete arra épült, hogy közel hozzák a Windows

Forms/MFC/Delphi programozókat a web fejlesztéshez, ugyanis az asztali fejlesztői

környezetben már megszokott fogd-és-vidd módszerrel gyorsan kialakíthatjuk a felületet,

gazdag szerveroldali komponensek segítségével és eseményvezérelt támogatással. A

webes környezetben eleinte nagyon csábító ajánlat volt, hogy nincs szükségünk

különösebb HTML, JavaScript tudásra, hogy előállítsunk egy komplex web alkalmazást.

Az alábbi táblázatban összehasonlítom a két ASP.NET-re épülő technológiát pár

szempont alapján:

Page 17: BSc Thesis - SimpleXpense

17

ASP.NET Web Forms ASP.NET MVC

Szerver

oldali

vezérlők

Az ASP.NET szerver oldali

vezérlők a böngészőtől függően a

megfelelő HTML és JavaScript

elemeket generálják számunkra,

hogy egységesen nézzenek ki a

vezérlőink. Sok vezérlő adatkötést

is támogat, amivel még

kényelmesebbé válik a

használatuk.

Az MVC-ben egyáltalán nem

találhatók szerver oldali vezérlők, a

kliens oldali szabványos HTML

elemeket és az így kialakított

vezérlőket támogatja.

Természetesen használhatunk külső

féltől származó komponenseket is,

mint pl. a Telerik Kendo UI [14].

Állapot

megőrzés

A ViewState minden egyes

vezérlőről eltárolja az utolsó

állapotát egy láthatatlan mezőbe

csomagolva (hidden input).

Az MVC-ben nincs ViewState,

teljes mértékben ránk van bízva a

vezérlők állapotának a mentése

(hidden HTML mező, localstorage

stb.)

Esemény-

vezérelt

programo-

zási modell

A web fejlesztőnek nem kell

törődnie, hogy éppen POST, vagy

GET http metódus kezeli a

felhasználói interakciót. Csupán

felrak egy vezérlőt a

tervezőfelületre, és valamely

eseményét a vezérlőnek

megvalósítja a mögöttes

kódfájlban (code behind).

Az MVC egy teljesen más

architektúra szerint épül fel, nem

eseményvezérelt módon. A nézeten

található HTML elemeket a kliens

oldali szkriptek segítségével

kezeljük, innen továbbíthatjuk az

adatokat egy Controller action-

jéhez, illetve kérhetünk le további

HTML részleteket a szervertől.

Projekt ar-

chitektúra

A Web Forms világában nincs

megszabott projekt struktúra az

alkalmazások készítéséhez, így

magunk választhatjuk meg, hogy

milyen minta szerint szeretnénk

csoportosítani a rétegeket. A

probléma, hogy a

legkézenfekvőbb megoldás, ha a

felülethez tartozó mögöttes

kódfájlban írjuk az alkalmazás

logikát ezzel teljesen összekötve a

felhasználói felületet (UI) az

üzleti logikával.

Az MVC kiköveteli az egyes

rétegek különválasztását,

rendszerbe szervezését, melyet

kiegészítve a tervezési minták

használatával elkerülhetjük a

komplex, átláthatatlan, egymással

szorosan összefüggésben levő

kódokat.

Egység

tesztek

(Unit

Testing)

A mögöttes kód általában sok

eseménykezelőt tartalmaz, amik

nehézkesen tesztelhetők. A

mostanában népszerű Test Driven

Mivel a vezérlők (Controller-ek)

egy külön osztályban találhatók és

nem kapcsolódnak szorosan egy

nézethez, így a funkcionalitás, az

üzleti logika egyszerűen tesztelhető,

ezzel megfelelve a TDD fejlesztési

elveknek is.

Page 18: BSc Thesis - SimpleXpense

18

Development (TDD)3 fejlesztési

metódusban azonban különösen

fontos lenne a tesztelhetőség

minél hatékonyabb támogatása.

Teljesít-

mény

A ViewState az oldalon tárolódik,

ezzel növelve az oldal méretét,

így teljesítmény szempontjából

nem túl hatékony.

A ViewState hiányának

köszönhetően nincs automatikus

állapot kezelés, rajtunk múlik, hogy

mit szeretnénk megőrizni a

következő kérésig. Ennek

következtében gyorsabbak lehetnek

az oldalaink is.

Keresőop-

timalizálás

Az URL-ek fix ASPX

erőforrásokra mutatnak, query

string-ekkel dekorálva. Ez nem

felhasználóbarát és sérti a SEO

(Search Engine Optimization)

[10] előírásokat.

Gazdag URL útvonal építési

lehetőségek állnak

rendelkezésünkre, melyek

támogatják a RESTful interfész

kialakítását, ezáltal megfelelve a

keresőoptimalizálási elveknek is.

Párhuzamos

fejlesztés

Az ASPX oldalak szorosan

kapcsolódnak a mögöttes

kódfájlhoz, ezért körülményes

lehet, ha két külön fejlesztő

egyszerre akar egyazon nézeten és

a hozzá tartozó vezérlő logikán

dolgozni.

Az MVC rétegei gyengén függnek

össze egymással és így

megvalósítható az, hogy egy adott

funkcióhoz kapcsolódóan külön-

külön fejlesztő dolgozik a Model,

View és Controller rétegeken.

HTML kód

kezelhető-

sége

Sokszor nem tudjuk, hogy

pontosan milyen HTML kód

generálódik egy-egy vezérlőből,

így nehézkes együttműködni a

kliens oldali JavaScript

keretrendszerekkel, mint pl. a

JQuery [36].

Mivel az MVC a tisztán HTML

vezérlőkre és a kliens oldali

szkriptekre épít, így egyszerűen

együttműködhetünk a kliens oldali

keretrendszerekkel is.

2. táblázat: Az ASP.NET WebForms és MVC összehasonlítása [11]

Megvan tehát mindkét technológiának az előnye és hátránya, azonban az MVC

segítségével úgy gondolom, hogy jobban meg tudunk felelni a felhasználók elvárásainak.

Az egész ASP.NET MVC keretrendszerre elmondható, hogy egy kiváló alapot nyújt

nagyobb alkalmazások webes fejlesztéséhez számtalan testreszabási lehetőséggel, ezért

is választottam ezt a technológiát a vékonykliensem megvalósításához.

3 Test Driven Development (TDD) – Egy olyan programozási technika, ahol egyszerre írjuk újra

és újra a forráskódot és az automatikus tesztet végző kódsorokat, míg nem teljesítettük az összes tesztet

sikeresen és a kívánt követelményeknek megfelelünk.

Page 19: BSc Thesis - SimpleXpense

19

2.2 Vizuális komponensek

Az alábbiakban a web kliens fejlesztése során felhasznált vizuális komponenseket

ismertetem pár szóban, melyek nagy segítséget nyújtottak a korszerű felhasználói felület

kialakításában.

2.2.1 Twitter Bootstrap

A Twitter Bootstrap [12] egy JavaScript/CSS könyvtár, mely elsősorban a design

szempontjából segít a web fejlesztésben, sok-sok komponenst biztosítva számunkra.

A szakdolgozatomban a 2.3.2-es verziót használtam, ugyanis ehhez fel tudtam

használni az ingyenesen elérhető TwitterBootsrapMVC [13] csomagot is, ami az

ASP.NET MVC-t egészíti ki HTML generáló segéd metódusokkal (HTML helper), hogy

még egyszerűbben használhatóvá váljon az amúgy gazdagon dokumentált könyvtár.

A bootstrap egyik fő építő eleme a Grid (táblázat) rendszer, mely 940 pixel

széles, összesen 12 oszlopra osztható fel és képes reszponzív4 módra is.

2.2.1.1 Felhasznált komponensek

A Grid rendszeren kívül az alábbi komponenseket használtam fel a web kliens

fejlesztése során:

Form: A bootstrap stílusfájl sok CSS osztály definíciót biztosít arra, hogy letisztult

megjelenésű űrlapokat és elegáns beviteli mezőket készítsünk.

Button és button dropdowns: Gombokat és legördülő

menüket hozhatunk létre csupán a megfelelő HTML inputok

és CSS osztályok alkalmazásával, ahol a gombok színe a

funkcióra jellemző plusz információt ad. (pl. piros – veszély,

zöld – siker, kék – elsődleges).

4 Reszponzív web design – Egy olyan web dizájn módszer, mely a különböző méretű és felbontású

kijelzőkhöz eltérő stílus szabályokat alkalmaz, de ugyanazt a tartalmat jeleníti meg minden eszközön. Így

akár mobilról böngészve is kényelmesen használhatóvá válik az weboldal.

2-4. ábra: Gombok és

legördülő menü használata a

web kliensben

Page 20: BSc Thesis - SimpleXpense

20

Navbar: A navbar CSS osztály használatával stílusos menüket készíthetünk, melyet

az alábbi kép is illusztrál:

2-5. ábra: Bootstrap stílusú menü részlet (web kliens)

Modal: Modális dialógus ablakokat

tudunk megjeleníteni minimális

JavaScript segítségével különböző

események bekövetkezésekor.

ProgressBar: A ProgressBar

egy állapotjelző sávot jelenít meg, melyet tipikusan egy (hosszú) folyamat aktuális

állapotának a kijelzésére használnak. Az alábbi képen az eredeti funkcionalitástól

eltérően a ProgressBar-t a kiadások/bevételek arányának ábrázolására használtam:

2-7. ábra: Kiadások és bevételek aránya a Bootstrap ProgressBar használatával (web kliens)

Glyph-icons: Egy kiegészítő ikonkészlet, amit szinte minden komponensben fel

tudunk használni. A menüben található kisképek is ebből az ikonkészletből

származnak (2-5. ábra).

Természetesen ezeken kívül még számos hasznos komponenssel rendelkezik,

melyek mindegye példakódokkal van illusztrálva a Bootsrap dokumentációjában [12].

2.2.2 Telerik Kendo UI

A Telerik Kendo UI [14] több, mint 70 grafikai és webes komponenst biztosít az

ASP.NET MVC számára, kliens és szerver oldali vezérlők formájában is.

2.2.2.1 Felhasznált komponensek

Az alábbi kliens oldali vezérlőket használtam fel a webes projektben:

DatePicker: Dátumválasztó komponens, mely

beállítható, hogy éppen milyen intervallumot mutasson

(csak évek, csak hónapok, hagyományos havi-napi

bontás, stb.)

2-6. ábra: Tranzakciók törlése dialógus (web kliens)

2-8. ábra: Dátumválasztó

komponens

Page 21: BSc Thesis - SimpleXpense

21

Combobox: Hagyományos legördülő menü, mely támogatja a keresést is.

NumericTextBox: Számokat (és mértékegységet) tartalmazó beviteli mező,

mely kiegészül egy léptető sávval, amivel meghatározott egységenként tudjuk

változtatni az értéket.

2-9. ábra: Tranzakció összege (NumericTextBox) és a valuta kiválasztása (Combobox)

Chart: Számos látványos grafikon hozható létre a Chart komponens

segítségével, mely szerver és kliens oldali adatkötést is támogat. Az alábbi

kódrészlet a web kliens kördiagramját definiálja, melyet a 4-9. ábra illusztrál:

@(Html.Kendo().Chart(Model) .Name("chart") .Title(title => title.Text(ViewBag.ChartTitle)) .ChartArea(chartArea => chartArea.Background("transparent")) .Series(series => { series.Pie(model=>model.Value, model=>model.Name, model => model.Color) .Labels(labels => labels .Visible(true) .Template("#= category # - #= kendo.format('{0:P}', percentage)#") .Align(ChartPieLabelsAlign.Column) ); }) .Legend(legend => legend.Position(ChartLegendPosition.Top)) .Tooltip(tooltip => tooltip .Visible(true) .Format("({0:0.00})") .Template("#= category #: #= kendo.format('{0:0.00}',value) # " + ViewBag.Currency) ) )

A Kendo UI kiegészítő nem ingyenes, azonban a látványos komponenseivel egy

újabb szintre emeli a web alkalmazásunkat, olyan gazdag vizuális élményt nyújtva, mely

akár új felhasználókat is csalogathat a rendszerbe, így idővel megtérülhetnek a befektetett

költségek. A részletes dokumentáció segít az eligazodásban, ám ha problémába

ütköznénk, akkor a Kendo UI fejlesztői is készséggel állnak a rendelkezésünkre. A próba

verzióban is megismerkedhetünk az összes komponenssel, azonban elérhető egy

ingyenes, nyílt forráskódú egyszerűsített verzió is Kendo UI Core néven, több, mint 40

HTML5 és JavaScript vezérlőt tartalmazva.

Page 22: BSc Thesis - SimpleXpense

22

2.3 Windows Phone 8

A Microsoft 2012. októberén adta ki a Windows Phone 8 [15] platformot, egy új

generációs mobil operációs rendszert. A Windows Phone 8 (WP8) szakít az előd

Windows CE architektúrára épült alapjaival, az új rendszer már a Windows NT kernel

alapokon nyugszik, sok-sok komponenst közösen használva a Windows 8 operációs

rendszerrel.

A szakdolgozatom írása közben, 2014. április 2-án hivatalosan is megjelent a

Windows Phone 8.1 (WP8.1) operációs rendszer, egy hosszabb fejlesztői tesztet

követően. Az újítások között szerepel az értesítő központ, az Internet Explorer 11-es

verziója, mely képes szinkronizálni Windows 8.1 és WP 8.1 készülékek között, az élő

csempék (live tiles) is kibővültek a start képernyőn, a Cortana hangfeldolgozó asszisztens

segítségével pedig könnyedén navigálhatunk a rendszerben beszéd alapján. A Microsoft

a jobb támogatottság érdekében a hardver követelményeken is változtatott, a WP8.1

megjelenésével immáron nem követelmény, hogy az eszközök fizikailag három gombbal

rendelkezzenek (vissza, start és a keresés), ezek a vezérlő gombok lehetnek szimulálva is

a felületen. Ezzel az enyhítéssel a gyártók fejleszthetnek olyan készülékeket, melyek akár

Android és Windows Phone operációs rendszerrel is képesek üzemelni.

A továbbiakban a Windows Phone 8 rendszert fogom ismertetni, ugyanis a

költségnyilvántartó keretrendszer mobil kliense is ebben a környezetben készült.

2.3.1 Felület

A platform egyik fő ismertető jele a METRO stílusú felület. A METRO dizájn elvei a

modern és letisztult megjelenést képviselik, ahol a hangsúly a tipográfián és a tartalmon

van. A felületen található élő csempék (live tiles) az infografikus irányelvet követve a

tartalomból mutatnak élő, mozgó képeket, ezáltal sokkal személyesebbnek érezzük őket.

Ezzel ellentétben az ikonografikus elv képviselői (pl. Apple iOS) a valódi világ

objektumait képezik le minél életszerűbben, a hiper-realizmus jegyében, ahol az analóg

világ technikailag minél tökéletesebb digitális megfeleltetése a cél. A Windows Phone

megjelenésében jelentősen különbözik a riválisaitól, melyet az alábbi ábra is szemléltet:

Page 23: BSc Thesis - SimpleXpense

23

2-10. ábra: Android, Windows Phone 8 és az iOS felülete

2.3.2 Az alkalmazás életciklusa

A telefonon egyetlen alkalmazás lehet az előtérben aktív egyszerre. Egy futó

alkalmazás többféleképpen is „alvó” (dormant) állapotba kerülhet:

Hívás érkezik, miközben fut az alkalmazás

Az alkalmazás Launchert vagy Choosert használ

Start gomb megnyomásának hatására

Megjelenik a zároló képernyő bizonyos idejű inaktivitás után

Az alvó állapotban a program továbbra is a memóriában marad, azonban semmi

sem garantálja, hogy az alkalmazásunk valaha is folytatódni fog, így a deaktiválás során

szükségünk van az aktuális állapot elmentésére. Ha az alvó állapotból újra „futó”

(running) állapotba kerül egy alkalmazás, akkor arról az oldalról fog folytatódni, ahonnan

deaktiválták, az aktiválás során betöltve a korábbi állapotot a memóriából. [15]

Ha az operációs rendszer kifutna a memóriából, akkor eldobja a legrégibb „alvó”

(dormant) alkalmazásnak a mentett állapotát, ezzel felszabadítva a memóriát. Ezt a

folyamatot nevezzük „sírkőbe zárásnak” (tombstoning). Ha egy „sírkőbe zárt”

(tombstoned) alkalmazást újra aktiválni szeretnénk, akkor annak a teljes állapotát újra be

kell töltenünk az alkalmazáshoz tartozó tárból. [16]

Az alkalmazás életciklusát az alábbi ábra szemlélteti:

Page 24: BSc Thesis - SimpleXpense

24

2-11. ábra: Windows Phone alkalmazás életciklusa [15]

2.3.3 Hardver követelmények

Az alábbi felsorolásban a WP8 mobil készülékekre előírt hardver

követelményeket tekinthetjük meg:

Képernyő: Windows Phone 7: kizárólag 800x480 (WVGA, 15:9),

Windows Phone 8: 800x480 (WVGA, 15:9), 1280x720 (720p, 16:9) vagy

1280x768 (WXGA, 15:9), Windows 8.1: új felbontás 1920x1080 (1080p)

Kapacitív érintés érzékelés: Minimum 4 pontos

Processzor: Qualcomm Snapdragon S4 dual-core vagy Snapdragon 800

Memória: min. 512MB RAM a WVGA és min. 1GB RAM a 720p/WXGA/1080p

felbontásokhoz. Legalább 4 GB flash memóriával rendelkezzen

Grafikus egység (GPU): DirectX renderelés támogatása hardveres gyorsítással

(Direct3D), programozható GPU-val

Kamera: Autófókuszos, legalább 5 megapixeles, opcionálisan előlapi kamera is

Szenzorok: A-GPS, gyorsulásmérő, fényérzékelő, közelségérzékelő, opcionális

iránytű és giroszkóp

Gombok: Alábbi gombokkal rendelkeznie kell: Start, Keresés, Vissza, Kamera,

Hangerőgombok, Kikapcsoló/bekapcsoló/billentyűzár gomb. Az első 3 gomb

csak Windows Phone 7/8 esetén kötelező.

2.3.4 Fejlesztés Windows Phone 8 platformra

A fejlesztés során törekedjünk arra, hogy igazi felhasználói élményt adjunk,

hiszen az élmények ragadják meg igazán a METRO elveket.

Page 25: BSc Thesis - SimpleXpense

25

A Windows Phone 8 közös alapokon nyugszik a Windows 8 operációs

rendszerrel. A CoreCLR a .NET keretrendszer CLR (Common Language Runtime)

magja, erre az alapokra épül a mobil platform, mely segítségével jól kihasználhatjuk a

többmagos környezetet, modern programozási technikákat és mintákat alkalmazva.

Az alábbiakban a platformra jellemző néhány technikai újdonságot és a fejlesztés

során felhasznált kiegészítőket mutatom be [17]:

2.3.4.1 Aszinkron programozási modell

A .NET 4.5 egyik jelentős újítása, hogy C# 5.0-ban (illetve a Visual Basic 11-ben)

új nyelvi elemek jelentek meg az aszinkron programozási modell támogatásához,

melyeket ebben a mobil környezetben kiválóan tudunk alkalmazni. Ennek segítségével

egyszerűbb gyorsan reagáló, nem blokkolódó felületeket készíteni, így a felhasználói

elégedettség is növelhető.

2.3.4.2 Garbage Collector (GC)

A CoreCLR-ben számos hasonló szolgáltatás és optimalizált megoldás áll

rendelkezésünkre, mint a NET 4.5 CLR-jében, ezáltal sokkal hatékonyabb, mint a .NET

Compact keretrendszer, amit az előd Windows Phone 7 használt. Az új három generációs

szemétgyűjtő (Garbage Collector) többmagos CPU-ra van optimalizálva, alacsony

késleltetéssel és javított élettartam követéssel.

2.3.4.3 A fordítás folyamata

A telefonra írt .NET kód a felhőben fordul le az alkalmazás feltöltésekor, így egy-

egy alkalmazás gyorsabban indul. Ezt úgy éri el, hogy a forrás C# kód először köztes

kódra fordul (MSIL/CIL assembly), majd a felhőben az MDIL (Machine Dependent

Intermediate Language) fordítóhoz kerül, ami a nem változó kódrészeket natív kódra

fordítja és megjelöli azokat a részeket, melyek eszközfüggően változhatnak. A folyamat

végén keletkezik egy majdnem teljesen natív kód, melyet a legutolsó lépésben a

készüléken tovább fordítva teljesen natív DLL-t kapunk. Ha bármi változás, frissítés

történik az alkalmazásban, akkor a változó részek már gyorsan újrafordíthatók a

telefonon. Ezzel a felhőben történő előkészítéssel közel 50%-os teljesítménybeli

növekedést értek el a WP7 platform alkalmazás indulási sebességéhez képest. [18]

Page 26: BSc Thesis - SimpleXpense

26

2-12. ábra: Windows Phone 8-ra írt kód fordításának folyamata [15]

2.3.4.4 Kódmegosztás a Portable Class Library használatával

A megosztható osztálykönyvtárak (Portable Class Library) segítségével ugyanazt

a felügyelt .NET kódot felhasználhatjuk több platformon is (Silverlight 4+, WP7,

Windows Store alkalmazások stb.). Újrafelhasználható üzleti logikákat készíthetünk, ha

kiemeljük azokat a közös részeket, melyek más .NET-es környezetben is megállják a

helyüket.

2.3.4.5 Adatok tárolása

Az alkalmazások a privát adataikat az Izolált tárban (Isolated Storage) tárolhatják,

azon belül is több helyen:

Az alkalmazás beállításait az Application Dictionary-ben

A nem strukturált adatok fájlokban

Strukturált adatokat az adatbázisban

Az Isolated Storage alapértelmezetten az SQL Server Compact Edition (SQL CE)

adatbázis kiszolgálót támogatja, Code First megközelítéssel és a LINQ to SQL erejével.

2.3.4.6 Mobil kliens fejlesztéséhez felhasznált osztálykönyvtárak, csomagok

A költségnyilvántartó keretrendszer mobil kliensének fejlesztése során több

hasznos nyílt forráskódú (opensource) osztálykönyvtárat és csomagot használtam fel,

melyek közül párat az alábbi listában ismeretetek, a kliens forráskódjából származó

példakódokkal illusztrálva:

Page 27: BSc Thesis - SimpleXpense

27

PropertyChanged.Fody [19]

A csomag használatával az INotifyPropertyChanged interfész megvalósítása

válik gyerekjátékká. Ez az interfész nagy szerepet játszik WPF/Silverlight

környezetben (így WP8 esetén is), ahol gyakoriak az adatkötések (binding) egy-

egy vezérlőhöz. Az adatokban történt változásról értesülnie kell a vezérlőnek is.

Ez az értesítés események elsütésével valósítható meg, így minden tulajdonságot,

amit fel szeretnénk készíteni változás-értesítésre, ki kell bővítenünk monoton

módon egy PropertyChanged esemény hívással:

public class RegisterPageViewModel: INotifyPropertyChanged { private string fullName; public string FullName { get { return fullName; } set { if (fullName != value) { fullName = value; NotifyPropertyChanged(); } } } // . . . Other properties public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged( [CallerMemberName] string propertyName = "") { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }

A PropertyChanged.Fody segítségével, ha a kívánt osztályon használjuk az

ImplementPropertyChanged attribútumot, akkor az osztály tulajdonságaiba

automatikusan injektálódik a fentebb látott NotifyPropertyChanged() hívás

és a környezete fordítás időben. Így rövidebb kódot kapunk és jelentős időt

takaríthatunk meg pl. egy-egy ViewModel implementálása során:

[ImplementPropertyChanged] public class RegisterPageViewModel { public string FullName { get; set; } // . . . Other properties }

Page 28: BSc Thesis - SimpleXpense

28

Windows Phone Toolkit [20]

Ez a kiegészítő csomag a Windows Phone SDK-t új komponensekkel bővíti ki,

melyek között akadnak igen hasznos vezérlők is. A sok lehetőség közül mindössze

3 komponensre volt szükségem:

ListPicker: legördülő lista. Elemek közötti kiválasztás a cél,

valójában olyan, mint egy ComboBox vagy DropDownList mobilos

környezetben.

2-13. ábra: Nyelvválasztó komponens (ListPicker)

ExpanderView: lenyitható/összecsukható elem. Lista elemként

használtam több helyen is: a kategória választás során, az áttekintő

oldalon, illetve egy-egy tranzakció részletező oldalán. A fejlécre kattintva

ki/becsukhatjuk a tartalmat, így elrejthetjük a nem kívánatos elemeket egy

felsorolásban.

2-14. ábra: Kategóriaválasztó komponens (ExpanderView)

DatePicker: dátumválasztó komponens. A képen látható dátumválasztó

valójában egy egyedi User Control, ami a DatePicker-re építve

kiegészíti azt a jobboldali sarokban látható célkereszttel, amire kattintva

az aktuális napra ugrunk.

2-15. ábra: Dátumválasztó komponens (DatePicker)

AppBar Utils [21]

Az Application Bar a képernyő alján elhelyezkedő gombokat, menüelemeket

tartalmazza, melyek így egységes kinézetet biztosítanak az alkalmazások

számára. Ezek az AppBar elemek azonban alapvetően fix elemnek számítottak,

korlátozott testreszabási lehetőségekkel. Az AppBar Utils segítségével

leválthatjuk a WP8 SDK nyújtotta AppBar-t egy dinamikus verzióra, ahol

használhatunk adat kötéseket, triggereket és különböző akciókat is. Ezáltal a

Page 29: BSc Thesis - SimpleXpense

29

menüelemek lokalizálása sem jelent akadályt többé, és a viselkedésnek

megfelelően testre szabhatjuk őket. Az alábbi kódrészletben a kategória választó

oldal Application Bar kódja látható, melyen egyetlen gomb szerepel, az új

kategória hozzáadása. Ez a gomb csak akkor engedélyezett, ha adminisztrátori

jogosultsággal bírunk:

<i:Interaction.Triggers> <abu:AppBarItemTrigger Type="Button" Id="new" Text="{Binding Path=LocalizedResources.AppBarCreateNewCategory, Source={StaticResource LocalizedStrings}}" IsEnabled="{Binding IsAdmin}"> <ec:CallMethodAction MethodName="appBarNewBtn_Click" TargetObject="{Binding}"/> </abu:AppBarItemTrigger> </i:Interaction.Triggers>

Coding4Fun Toolkit [22]

Ez a kiegészítő tartalmaz néhány igen hasznos vezérlőt a Windows Phone

platformra. Nekem csupán a MessagePrompt vezérlőre volt szükségem, mellyel

a hagyományos MessageBox dialógus ablakot cserélhetjük le egy testre szabható

verzióra. Az alábbi képen a jelszó emlékeztető dialógus látható, melyen

lehetőségünk van megadni egy e-mail címet, ahova az új jelszót küldi a rendszer:

2-16. ábra: Jelszó emlékeztető dialógus (MessagePrompt)

A MessagePrompt tartalmát felépíthetjük több vezérlő használatával is, így az

igényeknek megfelelően készíthetjük el a szükséges dialógust.

Windows Phone IsoStoreSpy [23]

Ez valójában egy alkalmazás Windows 8-ra, mely arra hivatott, hogy a WP7/8

emulátorok IsoStore tartalmát áttekinthessük, ami nagy segítség lehet a fejlesztés

során.

Úgy gondolom, hogy ezek a csomagok, kiegészítők hasznosak lehetnek akár egy

másik Windows Phone projekt fejlesztése során is.

Page 30: BSc Thesis - SimpleXpense

30

A Windows Phone 8 a felügyelt .NET környezet erejének köszönhetően

kényelmesen fejleszthető, sebességben is felveszi a versenyt a vetélytársakkal. A teljesen

eltérő felhasználói felület és az egyedi megoldások teszik igazán érdekessé ezt a mobil

platformot.

2.4 WCF

A WCF (Windows Communication Foundation) [29] a Microsoft egységes

programozási modellje szolgáltatás-orientált (SOA – Service Oriented Architecture)

alkalmazások készítéséhez. A fejlesztők számára egy megbízható, biztonságos eszközt

kínál az egymástól eltérő platformok közötti együttműködéshez.

2.4.1 WCF architektúra és fogalmak

A WCF-ben két szereplő kommunikál egymással: a szolgáltatás és a kliens. Egy

szolgáltatás egy vagy több végpontot (endpoint) publikál, melyre a kliensek

csatlakozhatnak. A kliens és a szolgáltatás oldali végpontok között üzenetek mozognak.

2.4.2 Üzenetcsere minták

Az alábbiakban felsorolom, hogy mely üzenetváltási mintákat támogatja a WCF

[24]:

Kérés-válasz: a kliens üzenetet küld, a szolgáltatás válaszüzenetben válaszol.

Messze ez a leggyakoribb.

Egyirányú (OneWay): a kliens kérésüzenetére nincs válasz.

Duplex (Callback): a szolgáltatás visszahív a kliensbe, a szolgáltatás küld csak

üzenetet.

2.4.3 Végpontok

Minden szolgáltatás végpont három fő részből áll: Address (cím), Binding (kötés),

Contract (szerződés). Ezen alkotóelemekre szokás a WCF ABC-jeként is hivatkozni.

Page 31: BSc Thesis - SimpleXpense

31

2-17. ábra: WCF végpontok ABC-je

2.4.3.1 Address (cím) – hol?

A végpont címe (URL), amin keresztül a kliensek el tudják érni a szolgáltatást. A

költségnyilvántartó rendszer szolgáltatása a fejlesztés közben az alábbi címen volt

elérhető: http://192.168.0.200:1617/ExpenseService.svc

2.4.3.2 Binding (kötés) – hogyan?

A kötések írják le, hogy a kliensek hogyan tudnak kommunikálni a szolgáltatással.

Egy kötés meghatározza a kommunikációs protokollt, melyre a WCF sok lehetőséget

kínál (pl. BasicHttpBinding – HTTP alapért., NetTcpBinding – biztonságos, TCP alapú,

MsmqIntegrationBinding – MSMQ alapú alkalmazások kommunikációjához, stb.) [29].

A végpont és a kliens közötti párbeszéd XML formátumú SOAP üzenetekbe van ágyazva,

ezáltal a WCF platform független szolgáltatást képes nyújtani.

2.4.3.3 Contract (szerződés) – mit?

A szerződés azokat a műveleteket, metódusokat definiálja, amiket a végpont

nyújt. A szolgáltatás interfész műveleteinek leírása .NET-ben a megfelelő attribútomok

használatával történik, amiből aztán elkészül a megfelelő WSDL (Web Service

Description Language) + XSD (XML Schema Definiton) leírás, így a kliensek használni

tudják az interfész metódusait. Több féle szerződés típus létezik [25]:

Service Contract

Leírja azokat a függvényeket, amiket a szolgáltatás kiajánl a kliensek számára.

.NET-ben a megfelelő attribútumok segítségével tudunk egy interfészt elérhetővé tenni

WCF-et használva:

[ServiceContract] public partial interface IExpenseService { [OperationContract] string GetData(int value); }

Page 32: BSc Thesis - SimpleXpense

32

Az interfészt a ServiceContract, míg az interfész függvényeit

OperationContract attribútummal kell ellátni, hogy sikeresen definiáljunk egy

Service Contract-ot.

Data Contract

Azokat az egyedi adat típusokat definiálja, amiket a szolgáltatás leíró nyelv

alapértelmezetten nem ismerhet. Az egyedi osztályokat, illetve adattípusokat nem

ismerheti az XSD, így ezeket külön definiálnunk kell, hogy a kliensek is használni tudják

a szolgáltatás egy-egy metódusának paraméterlistájában, illetve visszatérési értékként fel

tudják dolgozni. A Data Contract létrehozásához az adatleíró osztályt DataContract, a

benne található publikálni kívánt mezőket pedig DataMember attribútummal kell ellátni:

[DataContract] public class DetailsItem { private string temp; [DataMember] public string Date; }

Message Contract

A WCF SOAP üzenetekkel kommunikál és ahhoz,

hogy teljesen kontrollálni tudjuk az üzenet formátumát,

használhatjuk a Message Contract-ot. Ennek segítségével a

teljes SOAP üzenet törzse és fejléce igények szerint

alakítható, míg a Data Contract és az Service Contract-ok

SOAP formátumát és sorosítását a WCF kezeli helyettünk.

Fault Contract

A Fault Contract a szolgáltatásban keletkező

hibákról, kivételekről nyújthat tájékoztatást a kliensek számára.

A projektemben a Service Contract és Data Contract szerződés típusokat

használtam a szolgáltatás implementációja során.

2-18. ábra: SOAP üzenet

struktúra

Page 33: BSc Thesis - SimpleXpense

33

2.4.4 WCF és WebAPI összehasonlítása

A Web API az ASP.NET MVC 4-es keretrendszer részeként érkezett, azonban

külön csomagként is elérhető. Használatával egy egyszerű REST5 [26] képes web

szolgáltatást építhetünk fel, ami leginkább a kliens oldali JavaScript-ek adatigényét tudja

kielégíteni [27]. A Web API egy ideális platform olyan szolgáltatások létrehozásához,

ahol a kérés és válasz is a HTTP-n keresztül történik. A szolgáltatás a kliens GET, PUT,

POST és DELETE kéréseire válaszol alapértelmezetten JSON vagy XML formátumban.

A HTTP-nek köszönhetően széles körű kliens oldali támogatottságot érhet el, legyen szó

akár a böngészőkről, okostelefonokról vagy asztali alkalmazásokról.

Az alábbi táblázatban egy rövid összehasonlítást láthatunk a Web API és a WCF között:

WCF ASP.NET Web API

Támogatott

szállítási

protokollok

Többféle átviteli protokollt is

támogat (HTTP, TCP, UDP

és egyebek) melyek között

könnyedén válthatunk.

Csak HTTP protokollon

működik. Első osztályú

programozási modellt biztosít

a HTTP protokoll felett.

Hálózati

adatforgalom

A SOAP protokollnak

köszönhetően ugyan

kényelmesebb használatot

biztosít a kliens szoftverek

számára, azonban a nagyobb

hálózati adatforgalmat

generál az átvitt adathoz

kapcsolódó meta-adatok,

kiegészítő szolgáltatások

miatt.

Alkalmasabb arra, hogy

szélesebb körben hatékonyan

elérhetővé tegyen egy

szolgáltatást a különböző

böngészők, mobil eszközök

között, ugyanis kevés extra

rakománnyal viszi át az adatot

a hálózaton, HTTP fölött.

Üzenet

típusok

Többfajta üzenet kódolást is

támogat (Text, MTOM,

Binary) ugyanazon üzenet

típus számára, melyek között

válthatunk.

Olyan web alapú API-k

(Application Programming

Interface) létrehozását

támogatja, melyek sokféle

média típust támogatnak. Pl.

XML, JSON, stb.

5 REST (Representational State Transfer) – Egy szoftver architektúra elosztott hipermédia

rendszerek számára, mely állapotmentes, kliens-szerver alapú, cache-elhető kommunikációs protokollon

alapul (tipikusan a HTTP-n). A REST egy egyszerű alternatívát biztosít az eszközök összekötéséhez.

Page 34: BSc Thesis - SimpleXpense

34

Biztonság

Támogatja a WS-* alapokon

nyugvó biztonsági

szolgáltatásokat, mint a

Megbízható üzenetváltás

(Reliable Messaging),

Tranzakciók (Transactions)

és Üzenet biztonság

(Message Security).

Alapszintű (biztonsági)

protokollokat és formátumokat

használ, mint a HTTP,

WebSockets, SSL, JQuery,

JSON és XML.

A magasabb szintű biztonsági

protokollokat nem támogatja

(pl. Transactions)

Üzenet iránya

Támogatja a kérés-válasz

(request-reply), egyirányú

(One Way) és a kétirányú

(Duplex) üzenetváltási

mintákat is.

A HTTP csak a kérés-válasz

üzenetküldést támogatja,

azonban ez kiegészíthető a

SignalR [6] és a WebSocket

integrációjának segítségével.

Szolgáltatás

leíró nyelv

A WCF SOAP szolgáltatást a

WSDL nyelv írja le, ami

támogatja az automatikus

kliens oldali proxy-k

generálását még a komplex

sémájú szolgáltatások

számára is.

Sokféle módon írhatjuk le a

Web API nyújtotta

szolgáltatást, kezdve az

automatikus generált HTML

segéd oldalakkal, melyek

leírják a kínált metódusokat,

egészen a strukturált meta-

adatokig az OData

támogatással rendelkező API-k

számára.

Elérhetőség A .NET keretrendszer

részeként érhető el.

A nyílt forráskódú ASP.NET

keretrendszer részeként érhető

el, de akár külön egységként is

letölthetjük.

3. táblázat: A WCF és a WebAPI összehasonlítása [28]

Általánosságban elmondható, hogy a WCF használatával biztonságos web

szolgáltatásokat építhetünk, számos átviteli közeg felett, míg az ASP.NET Web API

segítségével olyan HTTP alapú szolgáltatást építhetünk, mely széleskörű kliensoldali

támogatottsággal rendelkezik. A Web API-t akkor érdemes használni, ha REST képes

(RESTful) szolgáltatást akarunk építeni. Ugyan WCF is támogatja a REST végpontok

összeköttetését pl. a WebHttpBinding kötés használatával, azonban a Web API teljesebb

támogatottsággal rendelkezik ezen a téren.

Az általam fejlesztett keretrendszer szolgáltatásának megvalósításához azért a

WCF technológiát választottam, mert .NET környezetben a rendszer résztvevői így

könnyedén kommunikálhattak egymással és a kliens oldal ki tudta használni a SOAP

protokoll nyújtotta előnyöket.

Page 35: BSc Thesis - SimpleXpense

35

3 Specifikáció

Ebben a fejezetben a költségnyilvántartó keretrendszer feladatainak pontos

leírását, a funkciónak specifikálását tekinthetjük át. Ezt követően a felhasználói

szerepköröket és a rendszer architektúráját ismertetem.

3.1 Szoftver célja

A feladatom egy költségnyilvántartó keretrendszer fejlesztése volt .NET

alapokon. A szoftver célja, hogy lehetővé tegye egy háztartás vagy akár kisvállalat

költségvetésének nyilvántartását, a kiadások, illetve bevételek elektronikusan való

tárolását.

A programban az egyes tételeket kategóriákba rendezve tárolhatjuk. A rendszer

adminisztrátorai a vállalat, illetve háztartás igényei szerint testre szabhatják ezeket a

költség kategóriákat, melyekre a felhasználók felvehetnek tételeket különböző

paraméterek megadásával. A megvalósítás során fontosnak tartottam, hogy az elkészült

szoftver egyszerűen kezelhető legyen webes és mobil platformon is, ezzel is növelve a

felhasználói tábort. A mobil kliens nagy előnye, hogy a költségeket, illetve bevételeket

akár azonnal feltölthetjük a rendszerbe, akár egy szupermarketben vásárlás közben is –

ahol a blokkról fotót is készítünk a telefonunkkal – vagy egy sikeres üzlet

lebonyolításának pillanatában.

A fejlesztendő alkalmazással szemben elvárás, hogy keretrendszerként működjön,

azaz legyen egy központi alkalmazás, ami megvalósítja az üzleti logikát, tárolja a

szükséges adatokat és kiszolgálja a különböző platformokon megvalósított kliens

alkalmazásokat. A kliens alkalmazások a központi szoftverrel kapcsolatban állva friss és

egyazon adatokkal dolgozhatnak, egymással együttműködve.

Végső célom az volt, hogy egy felhasználóbarát kiadás nyilvántartó alkalmazás

csomag készüljön, ami bátran felveheti a versenyt az ebben a kategóriában létrejött

szoftverekkel szemben. A hangsúlyt nem csupán a funkcionalitásra helyeztem, hanem

legalább ugyanakkora részben egy korszerű felület kialakítását is kitűztem magam elé.

További célkitűzésként szerepelt, hogy a rendszer funkcionális bővítése, illetve újabb

kliens platformok fejlesztése ne jelentsen különösebb akadályt a fejlesztő számára.

Page 36: BSc Thesis - SimpleXpense

36

3.2 Funkciók

A keretrendszer funkciót az alábbi felsorolásban tekinthetjük át. Ezek a funkciók

minden kliens alkalmazásra érvényesek.

Felhasználók kezelése: A felhasználók regisztrálhatnak valamely kliens

alkalmazásból, ezután igénybe vehetik az összes felhasználói szintű

funkciót. Kizárólag regisztrált felhasználók használhatják a szoftvert,

hiszen teljes mértékben felhasználó orientált a termék. Az alkalmazáson

belül nincs értelme felhasználótól függetlenül kiadásokról vagy

bevételekről beszélni általánosságban, ez mindig egy felhasználóhoz kell,

hogy tartozzon. A regisztrált felhasználók szükség esetén kérhetnek jelszó

emlékeztetőt a regisztrációkor megadott email címre, illetve törölhetik is

magukat a rendszerből. Minden egyes felhasználóhoz tartozik egy egyedi

beállítás, ahol megadhatjuk, hogy milyen pénznemben történjen az

elszámolás, illetve, hogy a (külföldi) valutákban szereplő tételek

konvertálódjanak az elszámolás pénznemére vagy meg se jelenjenek.

Kategóriák: A rendszer adminisztrátorai kezelhetik a tranzakciókra

vonatkozó kategóriákat. Minden egyes tranzakciót (tételt) pontosan

egyetlen kategóriában tudunk felvenni az alkalmazásba. A kategóriák

hierarchikusan épülnek fel, a rendszer 2 szintet különböztet meg. Minden

alkategória hivatkozik a szülő kategóriájára. A szülő kategóriákról

tároljuk, hogy kiadás, illetve bevételi kategóriának számítanak-e. Egy

szülő kategória lehet pl. a Kiadás (Expense) vagy a Bevétel (Income).

Létrehozhatunk azonban semleges szülő kategóriát is (pl. Ajándék [Gift]),

melyre felvehetünk kiadásokat és bevételi tételeket is. Az alkategóriákról

a szülő kategória ismeretével együtt egyértelműen kiderül, hogy kiadás,

bevétel vagy semleges kategóriáról van szó. Ilyen alkategória lehet pl. az

Bevétel (szülő) / Fizetés.

Tranzakciók: A rendszerben szereplő tételeket tranzakcióknak nevezzük.

A felhasználók az előző pontban említett kategóriák közül egyet

kiválasztva felvehetnek egy új tranzakciót. Egy tranzakció csak kiadás

vagy bevétel lehet. A felvétel során kötelezően meg kell adnunk az

összeget, mely csak pozitív valós szám lehet. A rendszerben az előjelről

Page 37: BSc Thesis - SimpleXpense

37

az fog dönteni, hogy kiadás vagy bevétel kategóriában szerepel az összeg.

Továbbá kötelezően meg kell még adnunk egy dátumot is és a valutát.

Opcionálisan megadhatjuk még a következő adatokat is egy új

tranzakcióra vonatkozóan: fizetőeszköz, megjegyzés, helyszín, fénykép

(célszerűen a nyugtáról/számláról). A rendszerben szereplő tranzakciók

képezik az alapját a kimutatásoknak, illetve áttekintő listának. A már

felvett tranzakciók megtekinthetők, illetve törölhetők az áttekintő listából,

ahol havi és azon belül napi bontásban szerepelnek a tételek, kategóriákba

rendezve.

Kimutatás: A szoftver leglátványosabb elemei a kimutatás diagramok. A

diagramok kategóriák szerint vannak rendezve. Az egyes klienseken eltérő

diagramok lehetnek, véleményen szerint mobil kliens esetén pl. egy

kördiagram jobban áttekinthető. A webes kliens képes megjeleníteni kör,

illetve oszlopdiagramot is, itt nagyobb felbontást feltételezünk. A

megjelenítendő adatokat szűrhetjük évenkénti, havi, heti, illetve napi

bontásban, illetve megadhatjuk, hogy a csak a bevételekre vagy csak a

kiadásokra vagyunk kíváncsiak, esetleg mindkettőre egyszerre.

Valuta konvertálás: Lehetőségünk van valuták közötti átváltásra is. A

valuták és az aktuális árfolyamok egy külső szolgálgatótól érkeznek, az

átváltás mindig az aktuális napi árfolyamon történik.

3.3 Felhasználói szerepkörök

A rendszer felhasználói között két szintet különböztetünk meg. Az egyik

csoportot az „egyszerű” felhasználók, míg a másikat az adminisztrátorok alkotják. Az

„egyszerű” felhasználók a valódi használói a rendszernek, a kategóriák kezelésén kívül

minden funkciót igénybe vehetnek. Az adminisztrátorok egyetlen plusz kiváltsága, hogy

menedzselhetik a kategóriákat, azaz újakat vehetnek fel, illetve törölhetnek a meglévők

közül. A rendszert használni kívánó látogatóknak regisztrálniuk kell ahhoz, hogy elérjék

a funkciókat, így nem beszélhetünk látogatói csoportról. A regisztráció után

automatikusan felhasználó szerepkörbe kerülünk, adminisztrátori jogosultság az

adatbázisban tárolt felhasználó típusának kézi módosításával adható egy-egy leendő

felhasználónak, amihez ideális esetben csak az adatbázis szerver üzemeltetője férhet

hozzá. A szerepköröket az alábbi use-case diagram ábrázolja:

Page 38: BSc Thesis - SimpleXpense

38

3-1. ábra: Felhasználói szerepkörök use-case diagramja

3.4 Architektúra

A szoftver egy kliens-szerver alapú architektúrát valósít meg, ahol a szerver

kommunikál az adatbázissal, megvalósítja az üzleti logikát, amit egy interfészen keresztül

elérhetővé tesz a kliensek számára. A kliens alkalmazások egy-egy funkció használata

során a szerverhez fordulnak, majd a szerver válaszát feldolgozva megjelenítik a

szükséges adatokat.

A szerver egy külső valutaárfolyam szolgáltatóval is kommunikál, hogy minden

nap friss árfolyamokkal dolgozhassunk. A rendszer architektúráját a 3-2. ábra vázolja.

Page 39: BSc Thesis - SimpleXpense

39

3-2. ábra: Architektúra vázlat

A szerveren egy szolgáltatás fut, mely WCF-en keresztül kommunikál a

kliensekkel SOAP üzenetek formájában, HTTP protokoll felett (lásd 2.4-es fejezetben).

A valutaárfolyam szolgáltató (https://openexchangerates.org/) RESTful

szolgáltatást biztosít, JSON formátumban kínálva a szükséges adatokat, melyet a szerver

eltárol, időnként újra lekérve az aktuális árfolyamokat. Ez a szolgáltatás szükség esetén

cserélhető, mivel azonban egy meghatározott struktúrában várjuk az adatokat, szükséges

lehet a szerveren futó szolgáltatás módosítására is.

Az adatbázis lehet akár a szolgáltatást futtató vagy egy külön adatbázis szerveren

is. Használhatunk bármilyen .NET és Entity Framework kompatibilis adatbázis

kiszolgálót, legyen az akár az MSSQL, Oracle vagy a MySQL.

Lehetőségünk van a tervezett Windows Phone 8 mobil és ASP.NET MVC-re

épülő webes kliensek mellett egyéb kliens alkalmazásokat is megvalósítani (pl. Java,

Android, iOS alapokon), hiszen a WCF segítségével platform független szolgáltatást

tudunk nyújtani (amennyiben a kliens boldogul a SOAP üzenetekkel).

Page 40: BSc Thesis - SimpleXpense

40

4 Megvalósítás

Ebben a fejezetben a keretrendszer tervezésének és fejlesztésének lépéseit

mutatom be. Mivel a szakdolgozatom kereteibe nem férne bele minden lépés részletes

leírása, így próbáltam átadni a leglényegesebb információkat és egy-egy érdekesebb vagy

kihívást jelentő részletet kiemelni.

4.1 Adatbázis tervezése

A fejlesztés első állomása az adatmodell megtervezése volt. A tervezés során

először át kellett gondolnom, hogy milyen típusú adatokra lesz szükségem az alkalmazás

használata során. Továbbá azt is át kellett gondolnom, hogy az adatokat milyen formában

szeretném tárolni. A tárolás problémájára a megoldás viszonylag egyértelmű volt

számomra: a Microsoft SQL Server 2012 relációs adatbáziskelő rendszert választottam.

A döntés végkimenetelében szerepet játszott az, hogy a C#/.NET kiválóan együttműködik

ezen adatbázis kiszolgálóval, széleskörűen támogatott, valamint egyszerűen kezelhető. A

kiszolgálóval való kommunikáció kényelmesebbé tétele érdekében az Entity Framework

ORM (Object-relational mapping) [30] rendszert használtam.

4.1.1 Code First vagy Database First?

Az Entity Framework támogatja ezen kiszolgálóhoz a Code First megközelítést,

mely szemlélet szerint az egyes adatosztályok – mint entitások – és az osztályok között

levő kapcsolatok leképződnek adatbázis táblákra, valamint relációkba, amennyiben

megfelelő adatbázis kontextusba (DBContext) helyezzük őket. Ezt a módszert

választottam én is az adatbázis tervezése során, mert gyorsan létre tudtam hozni egy

adatbázist csupán az osztályok forráskódjának előállításával. Mindvégig kézben tudom

tartani az adatbázis tábláinak megfeleltethető osztályokat, nincsenek az adatbázis

sémából automatikusan generált osztályok (POCO entitások) ellenben a Database First

megközelítéssel szemben, ahol, ha a generált modellünket bővíteni szeretnénk valamilyen

új funkcióval vagy csupán egy új tulajdonsággal, akkor az csak úgy lehetséges, ha

kiterjesztjük a parciális modell osztályunkat. Ezzel sok-sok modell-kiterjesztés születhet,

ami átláthatatlanná teheti a projektet.

Természetesen megvannak a Database First technikának is az előnyei. Ide tartozik

az, hogy optimalizálhatjuk a táblák mezőit a megfelelő típusok, méretek megadásával

Page 41: BSc Thesis - SimpleXpense

41

(igaz attribútumok segítségével a Code First módszert is finomíthatjuk valamilyen

mértékben), létrehozhatunk tárolt eljárásokat, triggereket. Az adatbázisokkal gyakran

foglalkozó szakértők talán jobban kedvelik a már bevált adatbázis létrehozási

módszereket, ahol teljesen testre szabhatják az igényeknek megfelelően az adatbázis

szerkezetét, és optimalizálhatják a rendszert. Kimerítőbb munka, azonban a befektetett

energiák könnyen megtérülhetnek.

A sémában történt változások frissítését mindkét technika támogatja. Code First

esetén az Entity Framework migrációs képességét használhatjuk ki, míg a Database First

módszernél frissíthetjük a generált modellt a séma aktuális állapota alapján. Ha

szeretnénk nyomon követni az adatbázisban történt változásokat, a különböző verziókat,

akkor a Code First migrációk hatalmas segítséget nyújthatnak számunkra, ahol egy

migráció hozzáadásával új fájl keletkezik időbélyeggel és egy általunk választott névvel,

majd ebben a fájlban automatikusan legenerálódnak a modellben történt változások egy

UP() és DOWN() függvényben. Az UP() függvény alkalmazza a modellben történt

változásokat, míg a DOWN() függvény eltávolítja a már nem kívánatos elemeket

(rollback). Mivel az adatbázis séma teljes mértékben a kódtól függ, a forráskód

verziózása is rendelkezésünkre áll. Bele tudunk avatkozni a kontextus inicializálásába is,

ahol például kezdeti üzleti adatokkal tölthetjük föl az adatbázisunkat. A verziózás

megvalósítása adatbázis oldal esetén már koránt sem olyan triviális feladat. [31]

4.1.2 Az adatbázis séma

Most áttérek a költségnyilvántartó rendszer adatbázis-tervének a

végeredményére. A tervezés több lépcsőből állt, először összegyűjtöttem a tárolandó

adatok listáját, amiket adatbázis entitásokba csoportosítottam, majd a folyamatos

finomítások után végül meghatároztam az entitások közötti kapcsolatokat is.

A tervezés befejeztével az alábbi Code First entitás modell készült el:

Page 42: BSc Thesis - SimpleXpense

42

4-1. ábra: Adatbázis séma

Page 43: BSc Thesis - SimpleXpense

43

4.1.3 Táblák és attribútumok

Az alábbi táblázatban a Code First segítségével generált adatbázis tábláit és

attribútumait tekinthetjük át. A táblák egyes oszlopaihoz rövid leírás tartozik, ami

tisztázza az attribútumok tárolási funkcióját.

Tábla Tárolási

funkció Oszlop Leírás

Users Felhasználók

adatai

Id Elsődleges kulcs

FullName A felhasználó teljes neve

Username A felhasználó azonosítója

Password A felhasználó jelszava (MD5

algoritmussal hashelt)

Email A felhasználó e-mail címe

Type Felhasználó szerepköre: admin /

user

Settings Felhasználó

beállításai

Id Elsődleges kulcs

BaseCurrency Alapértelmezett valuta

CurrencyConvert

Konvertálja az alapvalutát más

valuta esetén vagy csak az

alapvaluta tételei jelenjenek meg?

Language Használt megjelenítési nyelv

Transactions Tranzakció

adatai

Id Elsődleges kulcs

Note Megjegyzés

Date Tranzakció időpontja

Amount Tranzakció összege

IsExpense A tranzakció kiadás-e?

User_Id

Idegen kulcs

Payment_Id

Currency_Id

Location_Id

Category_Id

RecurringTransactions6

Ismételődő

tételek

(tranzakciók)

Id Elsődleges kulcs

LastDate Utolsó bekövetkezési időpont

NextDate Következő bekövetkezési időpont

Note Megjegyzés

Amount Tranzakció összege

IsExpense A tranzakció kiadás-e?

User_Id Idegen kulcs

Frequency_Id

Frequencies Ismétlődési

gyakoriság

Id Elsődleges kulcs

Freq Értesítési gyakoriság

Receipts Számlák,

blokkok

Id Elsődleges kulcs

Photo Számláról (bizonylatról) készült

fotó byte tömbként tárolva

Transaction_Id Idegen kulcs

Payments Fizetési

típusok

Id Elsődleges kulcs

Type Fizetőeszköz típusa

6 Ismételődő tételek jelenleg nincsenek kezelve az alkalmazásban, későbbi bővítési lehetőséghez

egy kiindulási alap ez a tábla

Page 44: BSc Thesis - SimpleXpense

44

Categories Kategóriák

Id Elsődleges kulcs

Name Kategória megnevezése

IsExpense Azt jelöli, hogy a kategória kiadás-

e vagy bevétel

ParentCategory_Id

Idegen kulcs, egy adott kategória

szülőjére mutat. A

gyökérelemeknél a szülő kategória

azonosítója NULL

Locations Helyszínek

adatai

Id Elsődleges kulcs

Longitude Hosszúsági koordináta

Latitude Szélességi koordináta

Altitude Magassági koordináta

Postcode Irányítószám

City Város

Street Utca

Country_Id Idegen kulcs

Countries

Helyszínekhez

kapcsolódó

országok

Id Elsődleges kulcs

Name Ország neve

Currencies

Felhasználók

által használt

valuták adatai

Id Elsődleges kulcs

Code Valuta kód

Image Valuta szimbólum

Country_Id Idegen kulcs

4. táblázat: Az adatbázis tábláinak részletezése

4.1.4 Megjegyzések az adatmodellhez

Az adatmodell ebben a formájában nem támogatja a valuta átváltását bármely

dátumra visszamenőleg. Ha valamely kliens alkalmazás beállítások oldalán a valuta

átváltás opciót bekapcsoljuk, akkor a tranzakciós tételek mindig a lekérdezés aktuális

napjának árfolyamán lesznek konvertálva az alapvalutára. Az általam megvalósított

megoldás tehát nélkülözi a tétel dátumán érvényes valutaárfolyamot, mindig a

legfrissebbekkel dolgozik.

Az alábbiakban ismertetek egy elképzelést, mely szerint az adatbázis felkészíthető

lenne arra, hogy a tételeket a tranzakciós dátumnak megfelelő árfolyam szerint váltsuk

át. Ehhez először is szükségünk lenne az összes létező valutaárfolyamra azokon a

napokon, amelyeken történt tranzakció. Az architektúrában feltüntetett valuta kiszolgáló

támogatja a historikus valuta árfolyamok lekérdezését, azonban ez a lekérdezés időben

költséges művelet lenne minden egyes tétel esetén, amelyek külföldi valutában

szerepelnek. A művelet költségét csökkenthetjük azzal, ha a szerver adatbázisában

tároljuk a valutaárfolyamokat a számunkra szükséges dátumokon a következő tábla

felvételével: CurrencyRates(Id, Date, <Currency1...Currencyn>), ahol a

Currency1…Currencyn jelentik az egyes valuták értékét a mindenkori alapvalutához (1

dollárhoz) viszonyítva és az adott dátumra vonatkozóan. Még optimálisabb megoldás

Page 45: BSc Thesis - SimpleXpense

45

esetén csak azon valuták értékét tároljuk, amelyeket használunk is az adott napon. Ezáltal

az adatbázisban állandóan rendelkezésre állhatnak historikusan a szükséges valuta

árfolyamok, melynek egy részét a szerver memóriájában tartva gyorsan hozzáférhetőek

lennének.

4.2 Szerver és a szolgáltatás

A specifikációban feltüntetett szerver központi szerepet tölt be a szolgáltatás-

orientált architektúrában (SOA – Service Oriented Architecture). Feladata, hogy IIS alatt

futasson egy WCF szolgáltatást. Ez a szolgáltatás gyakorlatilag egy .NET

osztálykönyvtár, mely kommunikál az adatbázissal és egy külső valuta szolgáltatóval. A

DLL (Dynamic-link library) egy WCF interfészt ajánl ki a kliensek számára, ami HTTP

protokollon keresztül érhető el a kliensek számára és megvalósítja az üzleti logikát

elfedve az adatbázis hozzáférést a kliens szoftverek fejlesztői elől. A szolgáltatás teljes

forráskódja a Service projektben található.

4.2.1 Üzleti logika

Az üzleti logikát teljesen egészében lefedi az alábbiakban ismertetett interfész és

annak implementációja a mögöttes adatbázissal együtt.

4.2.1.1 Adatbázis kontextus

Az adatbázis kontextust megvalósító osztály egy új projektbe került (Data), mely

akár egy külön szerveren is üzemelhet a szolgáltatást futtató szervertől, ha bármi

indokolná. A kontextus létrehozásnál figyelni kellett arra, hogy a Lazy Loading ki legyen

kapcsolva, ugyanis bekapcsolt állapotában a WCF nem tudja sorosítani a tábla-

osztályainkat7. Ezek a modell osztályok egyébként DataContract-ok is egyben, illetve

az adattagjaik DataMember attribútumokkal vannak ellátva, ha már a WCF

kontextusában használjuk őket. A Lazy Loading kikapcsolásával veszítünk ugyan a

kényelemből a lekérdezések során, azonban legalább két egyéb lehetőségünk is van

betölteni a kapcsolódó táblákat: Eagerly Loading és Explicitly Loading [32]. Eagerly

loading esetén a LinQ lekérdezés közben tudjuk betölteni a kívánt kapcsolódó entitásokat

az Include(<path>) függvény segítségével. Explicitly Loading esetén ki kell

7 Adatbázis táblákba képződő C# osztályok, Entity Framework és a Code First segítségével.

Page 46: BSc Thesis - SimpleXpense

46

kényszerítenünk az explicit betöltését a kapcsolódó entitásnak, majd ezután ugyanúgy

használhatjuk az entitás már betöltött navigációs tulajdonságát, mintha a Lazy Loading

rendelkezésünkre állna. Lássunk egy-egy példát mindkét változatra a szolgáltatásból

hozott kódrészletekkel:

Eager loading példakód (egy felhasználó tranzakcióinak lekérdezése a kapcsolódó

táblákkal):

private IQueryable<Transaction> GetTransactionsByUser(int userID) { // Eagerly load related entites to a transaction var transactions = db.Transactions.Include("Category") .Include("Receipts").Include("Currency").Include("User"); // Get the user’s transactions var collection = from t in transactions where t.User != null && t.User.Id == userID select t; return collection; }

Explicit loading példakód (felhasználó törlése a kapcsolódó rekordokkal együtt):

public bool DeleteUser(int id, out string resultMsg) { try { var user = db.Users.Find(id); if (user == null) { resultMsg = "User not found!"; return false; } // Delete transactions of the user db.Entry(user).Collection(u => u.Transactions).Load(); var transactions = user.Transactions; if (transactions != null) { // Iterating over transactions of the user and delete them foreach (var t in transactions.ToList()) { db.Entry(t).Collection(t1 => t1.Receipts).Load(); . . . //Delete receipts associated with transaction db.Transactions.Remove(t); // Delete transaction } } . . . // Delete other related entites // Delete user db.Users.Remove(user); db.SaveChanges(); resultMsg = "Successfully deleted the user!"; return true; }

Page 47: BSc Thesis - SimpleXpense

47

catch (Exception e) { // Something went wrong resultMsg = e.Message; return false; } }

4.2.1.2 Interfész és adatok

IExpenseService

Erre a közös interfészre kapcsolódhatnak a kliensalkalmazások. A

specifikációban ismertetett funkciók mindegyike elérhető ezen keresztül.

Az interfész egy ServiceContract, melyben a metódusok mindegyike

OperationContract attribútummal van ellátva.

Az interfész, illetve a következő alfejezetben ismertetett interfészt megvalósító

osztály is parciális, azaz az implementáció több részre van bontva, ami a gyakorlatban

annyit jelent, hogy a kódok külön fájlokban szerepelnek a könnyebb áttekinthetőség és a

funkciók kategorizálása miatt. A teljes interfészt leíró fájlok tartalmát az alábbi

felsorolásban ismertetem:

IExpenseService.cs: A kiinduló IExpenseService interfészt tartalmazó fájl.

Csupán teszt jellegű metódusokat tartalmaz, az ezt követő fájlokban ennek az

interfésznek a parciális darabkái találhatók meg.

ICategory.cs: Kategóriák menedzselésére vonatkozó metódusok. Ide tartozik

egy kategória törlése, szülő –és alkategória felvétele (csak admin felhasználók

számára érhetők el), valamint a különböző lekérdezések.

ICountry.cs: A helyszínekhez kapcsolódó országok lekérdezése.

ICurrency.cs: Valutákhoz kapcsolódó metódusok gyűjteménye. Fel tudunk

venni az adatbázisba egy-egy valutát, lekérdezhetünk az árfolyam szolgáltatótól,

illetve konvertálhatunk egy összeget másik valutára. A valutaváltáshoz az

adatokat az https://openexchangerates.org/ szolgáltatja, ahol a regisztrált

felhasználók JSON formátumban kérdezhetik le8 a legfrissebb, valamint az elmúlt

napokra vonatkozóan az egyes valutákhoz tartozó átváltási rátát.

8 Ingyenes licencszerződéssel 1000 lekérdezés/hónap

Page 48: BSc Thesis - SimpleXpense

48

IPage.cs: Az egyes „oldalakra” vonatkozó adatok kérdezhetők le innen. 3

metódusa van: GetMainPageSource(…), GetOverviewSource(…),

GetDetailsSource(…), melyek mindegyike egy egyedi típusú

ObservableCollection-nel tér vissza. Alapvetően a mobil kliens korábban

elkészült felülete ihlette ezeket a metódusokat, hogy kiszolgáljon egy-egy

panoráma oldalt. Mivel azonban a web kliens is hasonló szerkezetű felületi

elemekkel és oldalakkal rendelkezik, ezért ott is tökéletesen használható volt.

IReport.cs: A kimutatásokhoz szükséges adatok lekérdező metódusai

tartoznak ide. Készült 4 különböző idő intervallumokra vonatkozó metódus (évi,

havi, heti és napi bontású), melyet később egyesítettem egy általánosabb

metódusba.

ITransaction.cs: Tranzakciók kezelése. Új tranzakció felvétele, meglévő

törlése, illetve lekérdezések tartoznak ide.

IUser.cs: A felhasználókra vonatkozó metódusgyűjtemény. Ide tartoznak a

következő funkciók: bejelentkezés, jelszó változtatás, törlés, lekérdezések,

beállítások mentése, illetve a jelszó egyezés ellenőrzése.

Természetesen az interfész metódusai által igényelt egyedi típusokhoz tartoznak

megfelelő osztályok, melyek mindegyike egy-egy DataContract.

4.2.1.3 Implementáció

A fentebb ismertetett interfészt egyetlen osztály valósítja meg, az

ExpenseService. Mint azt már olvashattuk, a teljes osztály itt is több fájlra lett bontva,

az interfész darabkákat tartalmazó fájlokkal összefüggésben:

ITransaction.cs TransactionOperations.cs,

ICurrency.cs CurrencyOperations.cs és így tovább…

Osztály szinten egy adatbázis kontextust tartok fenn, melyet az osztálypéldány

elpusztulásakor felszabadítok (Dispose minta [33]), így egy helyen cserélhető az aktuális

adatbázis kontextus és nincs szükség minden egyes adatbázis lekérdezésnél (valójában

LinQ to Entities lekérdezéseknél) létrehoznunk azt egy using blokkon belül. Hátránya,

hogy nincs lezárva az adatbázis kapcsolat a lekérdezés végrehajtása után.

Page 49: BSc Thesis - SimpleXpense

49

A szolgáltatás implementációból egy kódrészletet emelnék ki némi magyarázattal

együtt. A valuta szolgáltatóval való kommunikáció részletébe pillanthatunk bele, mely

során az érkezett adatokat egy statikus gyűjteményben (Currencies) tárolom el a

szerver memóriájában.

CurrencyOperations.cs kódrészletek:

// Get currencies from provider if they are not up to date private void GetCurrenciesIfNotUpToDate() { if (Currencies == null || Currencies.Count <= 0 || CurrencyLastUpdatedDate.Date < DateTime.Now.Date) {

// block async operation (wait for the result) AsyncContext.Run(() => this.GetCurrenciesAsync()); } } // Trying to get currencies from the provider (openexchangerates) // in JSON format private async void GetCurrenciesAsync() { var httpClient = new HttpClient(); await httpClient.GetStreamAsync("http://openexchangerates.org/api" + "/latest.json?app_id=" + OpenExchangeApiKey) .ContinueWith(r => { Stream responseStream = r.Result; // Serializing response var serializer = new DataContractJsonSerializer( typeof(CurrencyResponse)); var jsonResponse = serializer.ReadObject(responseStream) as CurrencyResponse; if (jsonResponse == null) return; lock (CurrencyLock) {

// Uploading response to the currencies collection Currencies.Clear(); foreach (var item in jsonResponse.GetCurrencies()) { Currencies.Add(item); }

// Set currency last updated time to now CurrencyLastUpdatedDate = DateTime.Now; } }); }

Page 50: BSc Thesis - SimpleXpense

50

A GetCurrenciesIfNotUpToDate() metódus minden valuta konvertálás

esetén hívódik meg, így egy ilyen környezetben képzeljük el. Hamar észrevehetjük, hogy

a metódus egyetlen feladata, hogy bizonyos feltétel esetén futassa a

GetCurrenciesAsync() függvényt. A feltétel akkor teljesül, ha üres a

valutaárfolyamokat tároló statikus kollekciónk (Currencies) vagy már elavult

árfolyamokat tartalmaz (jelenleg az 1 napnál régebbi árfolyamokat tekintem elavultnak).

Ekkor szeretnénk a külső árfolyam szolgáltatótól lekérdezni az aktuális állapotot és

feltölteni az árfolyam tárolónkat a friss adatokkal. Azt is megfigyelhetjük, hogy a hívandó

aszinkron valuta lekérdező függvény az AsyncContext.Run() metódusnak lett átadva

Action delegate típusú paraméterként. Ez az aszinkron kontextus a Nito AsyncEx

[35] osztálykönyvtárból származik. A feladata, hogy egy aszinkron függvényt szinkron

módon futtasson, tehát bevárja, míg feldolgozásra kerül a GetCurrenciesAsync()

függvényben indított httpClient.GetStreamAsync(<url>) kérés válasza, vagy

amíg nem keletkezik kivétel. Szükségem volt arra, hogy mindenképp szinkron módon

kérhessem el a valutákat, mert a hívás helye utána rögtön használni szeretném a friss

értékeket a valuta konvertáló függvényben.

Érdemes még figyelmet szentelni a valuták feltöltésekor használt zárra (lock).

Mivel egy web szolgáltatás kontextusában helyezkedik el az üzleti logika, ezért a

szolgáltatást megvalósító osztály statikus adattagjainak írásakor kétszer is fontoljuk meg

a zárak használatát. Úgy képzeljük el az egészet, mintha egy többszálú környezetben

lennénk, ahol párhuzamosan is indulhat egy-egy valuta-konvertálás. A többszálú

környezetet most a felhasználók kérései jelentik és bizony előfordulhat, hogy egyszerre

két kérés is befut, előteremtve a konkurenciát [35]. Ha nem szeretnénk, hogy hol az egyik,

hol a másik szál töltse fel a valuta gyűjteményt, ami könnyen duplikátumokat okozhat,

akkor érdemes zárolni a közösen használt erőforrást, hogy egyszerre csak egyvalaki férjen

hozzá, amíg a másik várakozni kényszerül.

Az üzleti logikát segítendő, a szolgáltatás tartalmaz pár statikus Helper metódust

is. Ide tartoznak a különböző bővítő metódusok (extension methods), a kimutatás diagram

színezéséhez használt színárnyalatot manipuláló függvények, adat-validációs

függvények, az e-mail küldéshez használt kódrészlet, illetve egy új véletlen jelszót

generáló függvény.

Page 51: BSc Thesis - SimpleXpense

51

4.3 Kliens alkalmazások

Ebben az alfejezetben a megvalósított kliens alkalmazásokat tekinthetjük át.

Túlzottan részletes leírás nem férne bele a dolgozat keretébe, így a megvalósítás

mérföldköveit mutatom be, külön kiemelve a fejlesztői szempontból érdekes, kihívást

jelentő problémák megoldását.

4.3.1 Mobil kliens (WP8)

Az első kliens, ami a fejlesztés során elkészült, az a Windows Phone 8 platformra

íródott mobil alkalmazás.

4.3.1.1 Felhasználók kezelése

A felhasználói adatok tárolása úgy valósul meg, hogy a telefon helyi tárolójában,

az IsoStore-ban jegyzem fel (szerializálom9) az aktuálisan bejelentkezett felhasználóhoz

tartozó objektumot. Így, ha egyszer sikeresen beléptünk az alkalmazásba, akkor a további

használat során automatikusan be leszünk jelentkezve. A bejelentkező oldal csak akkor

jelenik meg, ha az alkalmazáshoz tartozó beállítások között nem található meg az aktuális

felhasználó adatai vagy éppen felhasználót váltunk.

4-2. ábra: Bejelentkezés és regisztráció mobilon

9 Szerializáció – segítségével egy objektum bájt-sorozatként reprezentálható egy fájlban. Ez a fájl

információt fog tartalmazni az objektum típusáról és minden adattagjáról, így az objektum állapotát

eltárolhatjuk.

Page 52: BSc Thesis - SimpleXpense

52

A mobil kliens az aktuálisan bejelentkezett felhasználó mellett megjegyzi a

beállított nyelv, valuta konvertálás és az alapvaluta beállításokat is, mely beállításokat

szintén az IsoStore-ban tárolok.

4.3.1.2 Felület

A kliens felületét a METRO elveknek megfelelően próbáltam létrehozni, ahol a

hangsúly a tartalmon van. A kialakított felület így letisztult és átlátható képet ad a

felhasználók számára.

A kezdőképernyőn egy Panorama vezérlő található, három elemmel:

A Transactions (tranzakciók) oldal a tranzakciókhoz tartozó műveletek

lebonyolításáért felelős. A gombok felett található egy piros-zöld sáv, ami

a kiválasztott hónapban a kiadások/bevételek arányát szemlélteti. Továbbá

itt találhatók még a funkció gombok, melyek a kiválasztott művelethez

tartozó oldalra navigálnak minket.

Az Overview (áttekintő) oldalon megtekinthetjük a bevitt tételeket

részletesen napokra lebontva az aktuális hónapra vonatkozóan.

A Settings (beállítások) oldalon végezhetjük el az alkalmazásra érvényes

beállításokat, melyek automatikusan mentésre kerülnek az alkalmazás

bezárásakor, illetve deaktiválásakor. Itt állíthatjuk be a nyelvet

(magyar/angol), az alapvalutát, illetve a valuta átváltás módját (csak az

alapvalutabeli tételek megjelenítése vagy az összes tétel jelenjen meg

szükség esetén konvertálva az alapvalutára).

Az alábbi képen láthatjuk a panoráma vezérlő alkalmazását a főoldalon, melyen

minden lényeges funkciót hamar elérhetünk.

Page 53: BSc Thesis - SimpleXpense

53

4-3. ábra: Panoráma főoldal

A legfontosabb funkció az alkalmazásban a tranzakciók bevitele. Tranzakció

hozzáadásakor a 4-4. ábra-n látható „Új tranzakció” feliratú képen is látható mezőket kell

megadnunk:

Amount (összeg): a tétel összege

Date (dátum): a tétel dátuma

Category (kategória): választhatunk megfelelő kategóriát attól függően,

hogy Income vagy Expense tételt rögzítünk. Lehetőségünk van új kategória

felvételére is, illetve egy kiválasztott kategória törlésére, ha admin

jogosultsággal rendelkezünk.

Payment (fizetőeszköz): fizető eszköz, valuta kiválasztása

Photo (photo): a telefon kamerája segítségével lefényképezhetjük a

tranzakcióhoz kapcsolódó számlát vagy blokkot. (nem kötelező)

Note (megjegyzés): megjegyzés hozzáfűzése (nem kötelező)

Location (helyszín): helyszín kiválasztása. Bing térkép segítségével tudjuk

kiválasztani a kívánt tartózkodási helyet (nem kötelező)

Az alábbi képen megtekinthetjük, hogyan néz ki egy új tranzakció hozzáadása és

néhány ehhez kapcsolódó választási lehetőség kezelőfelülete:

Page 54: BSc Thesis - SimpleXpense

54

4-4. ábra: Új tranzakció hozzáadása

4.3.1.3 Kimutatás

A bevitt tranzakciókról célszerű készíteni valamilyen kimutatást is, hogy jobban

átlássuk a kiadott vagy éppen a bejövő összegek eloszlását. A tételek grafikus

reprezentálására mobil platformon a kördiagramot választottam, melyen éves, havi, heti,

illetve napi bontásban tekinthetjük meg kategóriánként csoportosítva a

bevételeinket/kiadásainkat.

4-5. ábra: Kördiagram kimutatás a kiadásokról és bevételekről a mobil kliensen

A kördiagram ábrázolásához készítettem egy saját vezérlőt (user control), melyet

egy külső osztálykönyvtárban (class library) implementáltam, lehetővé téve, hogy esetleg

más WPF/Silverlight felületű alkalmazásokban is felhasználható legyen.

Az alábbi metódus felelős egy körszelet kirajzolásáért:

Page 55: BSc Thesis - SimpleXpense

55

private void drawPiChartSlice(double startAngle, double ratio) { Path path = new Path(); // . . . path kitöltés, vonalstílus Point point = new Point { X = 0.0, Y = 0.0 }; PathGeometry pathGeometry = new PathGeometry(); PathFigure pathFigure = new PathFigure(); pathFigure.StartPoint = new Point(0, 0); pathFigure.IsClosed = true; double angle = 360 * ratio / 100; if (angle == 360) { angle = 359.99; } // Starting Point LineSegment lineSegment = new LineSegment(); lineSegment.Point = new Point(this._radius, 0); // Arc ArcSegment arcSegment = new ArcSegment(); arcSegment.IsLargeArc = angle >= 180.0; arcSegment.Point = new Point(Math.Cos(angle * Math.PI / 180) * this._radius, Math.Sin(angle * Math.PI / 180) * this._radius); arcSegment.Size = new Size(this._radius, this._radius); arcSegment.SweepDirection = SweepDirection.Clockwise; pathFigure.Segments.Add(lineSegment); pathFigure.Segments.Add(arcSegment); pathGeometry.Figures.Add(pathFigure); path.Data = pathGeometry; RotateTransform rotate = new RotateTransform { CenterX = 0, CenterY = 0, Angle = startAngle }; path.RenderTransform = rotate; // Add pie chart slice to the placeholder this._piChartHolder.Children.Add(path); }

Bemeneti paraméterek:

startAngle – honnan kezdődjön a körszelet (fok)

ratio – körszelet mérete százalékban

Page 56: BSc Thesis - SimpleXpense

56

Létrehozok egy PathGeomerty típusú változót, melyben felépítem a körcikk

alakzatot. A ratio értékéből kiszámítom a körcikk belső szögét (látószög). A

megjelenítéshez szükségem lesz LineSegment-re a határoló vonal megrajzolásához,

valamint ArcSegment-re, a cikkely kirajzolásához. A cikkely szegmenset 90 foktól

kezdve rajzolom ki, az előzőleg számított látószöget felhasználva. A felparaméterezett,

elkészült szegmenseket felveszem a PathGeometry alakzatok listájába. Mindezek után

szükségem lesz egy forgatásra, hogy a megfelelő irányba álljon a körcikk (itt használom

fel a startAngle paramétert). A visszatérés előtt hozzáadom az elkészült útvonalat (Path)

a tárolóhoz (placeholder), ami jelen esetben egy Canvas vezérlő.

4.3.1.4 Lokalizáció

Az alkalmazás jelenleg angol és magyar nyelv között képes váltani valós időben.

A Windows Phone telefonoknál egy szokás, hogy az operációs rendszer beállításaiban

kiválasztva a telefon használati nyelvét azt az alkalmazások figyeljék induláskor, így egy

közös helyen válthatunk nyelvet. Adódik azonban néhány probléma ezzel a megoldással:

nem tudunk valós időben nyelvet váltani

szükségünk lehet újraindítani a telefont egy új nyelv kiválasztása után

az éppen futó alkalmazásunk Running állapotból Tombstoned állapotba

kerül, tehát a használat folytonossága megtörik (lásd 2.3.2-es fejezetben)

Így feltétlenül szükségét éreztem annak, hogy a kliensalkalmazáson belül is

lehetőség legyen nyelvet változtatni. A megoldáshoz át kellett gondolnom, hogy

miképpen lehetne Culture-t váltani úgy, hogy arról az érintett elemek is értesüljenek.

Alapvetően minden UI elem, amin bármiféle szöveg van

a LocalizedStrings osztályra van kötve (bind-olva), ez tartalmazza az

aktuális AppResources referenciát (itt találhatóak a név – érték párokban megadott

szöveg fordítások).

Amikor a felületen a nyelvválasztó gombra kattintunk, akkor az alábbi metódus

gondoskodik arról, hogy kicserélje az aktuális alkalmazás Culture-t, ami egyben azt is

jelenti, hogy a megfelelő AppResources.resx fájl kerül felhasználásra (pl.

AppResources.hu.resx - magyar nyelv esetében). Az átadott paraméter a kívánt

kultúra rövidítése (hu, en-US):

Page 57: BSc Thesis - SimpleXpense

57

public void SetUILanguage(string locale) { CultureInfo newCulture = new CultureInfo(locale); Thread.CurrentThread.CurrentCulture = newCulture; Thread.CurrentThread.CurrentUICulture = newCulture; AppResources.Culture = newCulture; ResourceTracker.OnPropertyChanged("Culture"); //. . . Set the FlowDirection of the RootFrame to match the new culture. //. . . Set the Language of the RootFrame to match the new culture. }

A bind-olt UI elemek azonban erről a változásról alapesetben nem fognak

értesülni, így létrehoztam egy statikus osztályt (ResourceTracker) egy eseménnyel,

amit minden AppResources.Culture értékadás után elsütök (kiemelt rész a kódban).

Erre az eseményre van feliratkozva a LocalizedStrings osztály (amire az UI

szövegek vannak kötve), amit kibővítettem, hogy implementálja

az INotifyPropertyChanged eventet. Így amikor elsül a ResourceTracker

eseménye, elsütök egy PropertyChanged eseményt a LocalizedStrings-en belül is

és így már frissülnek a felületen található szövegek is a kiválasztott nyelvnek

megfelelően.

Page 58: BSc Thesis - SimpleXpense

58

4.3.2 Web kliens (ASP.NET MVC)

A web kliens fejlesztéséhez az ASP.NET MVC 4 –es keretrendszert használtam

fel. A szükséges üzleti logikát a szolgáltatás már tartalmazza, így az igényes megjelenés

és a felhasználóbarát környezet kialakítására került a fő hangsúly.

4-6. ábra: Web kliens főoldal

4.3.2.1 Felhasználók kezelése

A felhasználók kezelése során nem támaszkodtam az MVC 4 autentikációs

csomagjára, helyette a szolgáltatásban megvalósított felhasználó kezelést vettem igénybe

kiegészítve a Session használatával. Típusos és egységes Session kezelést valósítottam

meg kontroller szinten, az alábbi módon:

BaseController.cs részlet:

public class BaseController { . . . // Session handler property protected BaseSessionData BaseSession { get { string sessionName = this.GetType().Name; return (BaseSessionData)(Session[sessionName] ?? (Session[sessionName] = new BaseSessionData())); } } . . . }

Page 59: BSc Thesis - SimpleXpense

59

[Serializable] public class BaseSessionData { public User User { get; set; } . . . }

Látható, hogy a BaseSessionData tároló osztályba csomagoltam a

felhasználóhoz tartozó adatokat. A Session kontrollerfüggő elemét a BaseSession

propertyben típusossá alakítva érhetjük el és így kényelmesen hozzáférhetünk az aktuális

felhasználói adatokhoz. Pl. int userid = BaseSession.User.Id értékadás a

Session-ből fogja előhalászni a felhasználó azonosítóját.

Szintén a BaseController-ben minden egyes kérés előtt ellenőrzöm, hogy az

aktuális felhasználó be van-e jelentkezve. Mivel a kontrollerek megvalósítják az

IActionFilter interfészt (Controller ősosztály implementálja), így lehetőségem

van beavatkozni az MVC szekvenciába, mielőtt egy Action-höz érkezne az eseménysor,

amennyiben felülírom (override) az OnActionExecuting(..) függvényt:

void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { // If we are at the login page do nothing var action = filterContext.RouteData.Values["action"].ToString(); var controller = filterContext.RouteData.Values["controller"].ToString(); if (controller == "Account" && (action == "Login" || action == "Register" || action == "PasswordReminder")) return; // Check if the current user is logged in before executing any action if (!this.LoggedIn) { // We are not logged in -> Redirect to the Login page filterContext.Result = RedirectToAction("Login", "Account"); } // . . . Load user settings to a ViewBag base.OnActionExecuting(filterContext); }

Ha a bejelentkező oldal felől érkezik a kérés (Account controller,

Login/Register/PasswordReminder action-je felől), akkor tovább engedjük az action

végrehajtással kapcsolatos szekvenciát, különben pedig ellenőrizzük, hogy a felhasználó

valóban be van-e jelentkezve (ezt a BaseSession-ből könnyedén kideríthetjük). Ha

nincs, akkor a login oldalra irányítjuk.

Page 60: BSc Thesis - SimpleXpense

60

A bejelentkezés, kijelentkezés, regisztráció, jelszó változtatás, beállítások

kezelése, valamint a felhasználó törlése funkciók természetesen már a szolgáltatással

kommunikálva valósulnak meg, szükség esetén módosítva a BaseSession-ben tárolt

aktuális felhasználóhoz tartozó tulajdonságok értékét.

4-7. ábra: Belépés és regisztráció felületének részlete

4.3.2.2 Kontrollerek

Minden egyedi vezérlőm a BaseController-ből származik, ami főleg a

felhasználók kezeléséről gondoskodik számunkra, mint ahogy azt az imént is láthattuk.

Emellett tartalmaz még néhány segédmetódust, melyekre szükségem lehet a leszármazott

vezérlőkben.

A kontrollerek fő feladata, hogy WCF-en keresztül kommunikáljanak a

szolgáltatással és átadják a szükséges adatokat a nézetek (View) számára. A vezérlőket

funkciójuk szerint csoportosítottam az alábbi osztályokra:

AccountController: Bejelentkező oldalhoz tartozó funkciók, illetve

bejelentkezés után a felhasználói profil funkciót menedzseli.

CategoryController: Ide tartozik a Categories oldal kiszolgálása

(kategóriák listázása), a kategória választó legördülő menük megjelenítése

(parciális nézetként), és természetesen a kategóriák kezeléséhez tartozó

segéd metódusok, action-ök.

CurrencyController: A valuta konvertáláshoz tartozó, listázó segéd

metódusok és a valutaválasztó legördülő elemet kiszolgáló action-ök

vannak itt.

Page 61: BSc Thesis - SimpleXpense

61

HomeController: A főoldalon található elemek megjelenítése. A

kiadás/bevétel arányát megjelenítő „grafikon”-hoz szükséges adatokat

szolgáltatatja.

OverviewController: Az Overview oldal tranzakció listázásához, a

részletek megjelenítéséhez és egy-egy tétel törléséhez tartozó action-ök

tartoznak ide.

ReportController: A kimutatás diagramokhoz tartozó vezérlő.

Parciális nézetben jeleníti meg a kívánt szűrési feltételeknek megfelelő

grafikont.

TransactionController: Új tranzakció felvételére vonatkozó

kontroller.

4.3.2.3 Nézetek

Igyekeztem a megjelenítés során minél több komponenst a kliens oldalról indítva

AJAX10 hívásokkal betölteni, ezzel is kényelmesebbé és gyorsabbá téve a szoftver

használatát. Természetesen vannak olyan nézetek is, melyek nem tartalmaznak parciális

elemet, ezek a Controller megfelelő action-jének ViewResult-jaiből állnak elő. A

kliens oldali szkriptekre külön hangsúlyt fektettem, szintén a látvány és az élmény

fokozása érdekében. A 4-8. ábra-n megfigyelhetjük, hogyan zajlik azon nézetek

előállítása, ahol egy-egy komponens betöltése AJAX módon történik:

4-8. ábra: Nézet előállítása AJAX segítségével [7]

Először egy kontroller action-je kezdeményezi a teljes nézet előállítását (1), majd

a kliens oldali jQuery [36] kód segítségével aszinkron módon betöltjük a nézet hiányzó

10 AJAX – Asynchronous JavaScript and XML. Aszinkron kliens-oldali kérések valósíthatók meg

vele, az oldal újratöltése nélkül. Ez növeli a honlap interaktivitását, sebességét és használhatóságát.

Page 62: BSc Thesis - SimpleXpense

62

kisebb elemeit (2 és 3). Ezen elemek tartalma később önmagukban is frissíthetők, nem

szükséges az egész oldalt újratölteni. Nézzük egy példát egy parciális nézet betöltésére:

Views/Report/Index.cshtml részlet:

<script type="text/javascript"> $(document).ready(function () { // . . . // --- INIT --- initExpenseBtn(); initTabPage(); // ------------- // . . .

function refreshChart() { // Get chart $.get('@Url.Action("Chart", "Report")' +

'?type=' + paramType + '&filter=' + paramFilter + '&date=' + paramDate + '&chartType=' + paramChartType,

function (data) { $("#barChartData").html(data); }); }

// . . . }); </script>

Ebben az esetben a kimutatás oldal (Report) letöltése után a böngészőben összeáll

az oldal (Document Ready), majd ennek a „kész” eseménynek a hatására az inicializálós

függvények (initExpenseBtn(), initTabPage()) meghívásával együtt lefut a

refreshChart() JavaScript függvény. Továbbá minden szűrési feltétel módosítása

esetén is meghívódik ez a függvény, legyen az akár kiadás/bevétel közötti váltás, dátum

módosítás vagy a szűrési idő intervallum (összes, év, hónap, hét, nap) változtatása. A

refreshChart() aszinkron módon visszaszól a szerver action-jének (URL-en

keresztül), hogy kellene még a hiányzó View darabka is. A szűrési paramétereknek

megfelelően a Report kontroller Chart action-jéhez fut be a kérés. Miután az action

feldolgozta és előállította az adatokat szükséges grafikonhoz, elküldi a választ a kliens

oldalnak, ami már tartalmazza a kért grafikont. A tartalmat betöltjük a barChartData

div-be, végül a kívánt grafikon megjelenik a böngészőben a teljes oldal újratöltése nélkül:

Page 63: BSc Thesis - SimpleXpense

63

4-9. ábra: Költség-kimutatás oszlop –és kördiagramokon

4.3.2.4 Felület

A web kliens projektet (WebClientApp) a Telerik Kendo UI for ASP.NET MVC,

Bootstrap 2.3.2 és a Twitter Bootstrap for ASP.Net MVC 4 1.0.9011 csomagok

felhasználásával készítettem. A Kendo UI csomagot a diagramok megjelenítéséhez

használtam fel, míg az utolsó kiegészítő HTML Helperekkel és segédosztályokkal

könnyíti meg számunkra a bootstrap használatát.

A felület kialakítása során reszponzív webdesign-t alkalmaztam, így akár mobilról

böngészve is kényelmesen használhatóvá vált az oldal. A reszponzivitást nagymértékben

elősegítette a Bootstrap (a bootstrap-responsive.css stílusfájl használatával),

azonban előfordultak olyan felületi elemek, ahol szükséges volt kiegészíteni a Bootstrap

stílus definícióit. Ezek a kiegészítések a Custom-responsive.css fájlban találhatók.

11 A NuGet csomag elérhetősége: https://www.nuget.org/packages/twitter.bootstrap.mvc4/1.0.90

Page 64: BSc Thesis - SimpleXpense

64

Ilyen felületi elem például az oldal alján elhelyezkedő lábléc (footer), melyre az alábbi

reszponzív stílus szabályok érvényesek:

@media (min-width: 1367px) and (max-height: 640px) { footer { display: none; } } @media (min-width: 768px) and (max-width: 1366px) and (max-height: 639px) { footer { display: none; } } @media (max-width: 767px) and (max-height: 1000px) { footer { display: none; } }

A fentebb látható CSS (Cascading Style Sheet) stílusleírás elrejti a böngésző ablak

aljára pozícionált footer-t a media-query-kben meghatározott szélesség és magasság

intervallumok esetén, amire azért volt szükség, mert ha kis méretben böngésszük az

oldalt, akkor belelógott az oldal tartalmába.

Az alábbi képeken láthatjuk, hogyan érvényesül a reszponzív design egy

okostelefon felbontásához igazítva:

4-10. ábra: Webes felület alacsony felbontáson megjelenítve

Page 65: BSc Thesis - SimpleXpense

65

5 Összefoglalás

A dolgozatban először a keretrendszer fejlesztéséhez felhasznált .NET-es

technológiákat ismertettem a kapcsolódó kiegészítő csomagokkal együtt, összehasonlítva

alternatív technológiai megoldásokkal is.

Ezután a specifikációban lefektettem a rendszerrel szemben elvárt

követelményeket, ismertetve a megvalósítandó funkciókat, a felhasználói szerepköröket

és a rendszer vázlatos architektúráját. A folyamat végén nekiláthattam az alkalmazások

tervezéséhez és fejlesztéséhez.

Utolsó lépésként a megvalósítás folyamatát közöltem, a tervezés során előforduló

döntésekkel és az implementációból kiemelt kódrészletekkel együtt. Először az adatbázis

tervezői döntéseit ismertettem, a végén bemutatva az elkészült adatbázis modelljét. A

további részekben a szolgáltatás által nyújtott interfész feladatköreit részleteztem. Az

elkészült kliens alkalmazásokat a legvégén mutattam be, kiemelve egy-egy platform

specifikus megoldást.

A megvalósított keretrendszer megfelel a specifikációban megfogalmazott

követelményeknek. Egy olyan költségnyilvántartó keretrendszer jött létre, mely stabil

alapokon nyugszik, valódi életben is használható és egyszerű bővítési lehetőségekkel

rendelkezik, akár újabb kliens alkalmazások hozzáadásával is. A felhasználók a felmerülő

költségeiket hatékonyan nyilvántarthatják a rendszer használatával. A tételeket

kategóriák szerint vehetik fel az összes létező valutában, melyeket aztán szűrhető

kimutatásokon és áttekintő listában böngészhetnek. Az egyes valuták alapvalutára történő

átváltását a rendszer automatikusan biztosítja, az aktuális napi árfolyamon. A kliensek

felülete letisztult, egyszerűen átlátható és könnyen kezelhető, a tartalmon van a fő

hangsúly. A rendszer az otthoni felhasználók és kisvállalkozások számára is egyaránt

hasznos lehet.

A szakdolgozat készítése során több .NET-es technológiát is tanulmányozhattam.

A szolgáltatás fejlesztéséhez a WCF-et használtam fel, míg a kliens szoftverek készítése

közben megismerkedhettem az ASP.NET MVC webes keretrendszerrel, a Windows

Phone 8 mobil platformmal, illetve az ezekhez kapcsolódó kiegészítő csomagokkal és

osztálykönyvtárakkal, mint pl. a jQuery, Telerik Kendo UI, Twitter Bootstrap és a

Windows Phone Toolkit.

Page 66: BSc Thesis - SimpleXpense

66

5.1 Továbbfejlesztési lehetőségek

A továbbfejlesztésnél a célom az lenne, hogy minél több felhasználó érdeklődését

keltsem fel a rendszer iránt, melyre az újabb kliens alkalmazások megvalósításával

nagyobb esélyeim vannak.

Azon is érdemes elgondolkodni, hogy mivel lehetne még hasznosabbá tenni a

rendszert. Az adatbázis tervezésénél utaltam rá, hogy az ismétlődő tételek kezelését

tervezem megvalósítani. Elég csak a havi befizetendő számlákra vagy a rendszeresen

érkező fix jövedelemre gondolni, és máris értelmét nyeri a funkció. Részletesebb szűrési

lehetőségeket, másfajta kimutatásokat is lehetne készíteni. Szintén utaltam rá, illetve egy

megoldási javaslatot is tettem arra, hogy egy külföldi tranzakció összegének alapvalutára

történő átváltásakor lehetőséget kellene adnom arra, hogy a tranzakció dátumának

megfelelő árfolyamon történjen a konverzió. Még egy jól működő párkapcsolatban,

illetve barátok között is gyakran okozhat problémát a költségek közös elszámolása. Az

egymással kapcsolatban álló fiókoknak a támogatását is szeretném megvalósítani, ahol

képet kaphatunk arról, hogy ki mennyivel tartozik a másiknak, hogy ne legyen többé

probléma a tartozások nyilvántartása sem.

A jelenlegi keretrendszer adatbázis lekérdezéseit szükséges lehet optimalizálni,

illetve átvizsgálni a rendszert teljesítmény szempontjából. A szolgáltatás sokszor fordul

az adatbázisszerverhez, pár adatot lehetne cache-elni. A megvalósított Windows Phone 8

mobil kliens alkalmazást WiFi mellett érdemes használni, mert gyakran kommunikál a

szolgáltatással. Egy optimálisabb megoldás lehet, ha a telefon helyi tárolójában tárolnám

a felhasználóhoz tartozó adatokat, tranzakciókat, majd ezt időnként szinkronizálom a

szerverrel (illetve a felhasználó is kérheti a szinkronizálást). Ezzel csökkenne a mobil

adatforgalom, viszont nem mindig legfrissebb adatokkal dolgoznánk. Megfontolandó,

hogy a szélesebb kliensoldali támogatottság érdekében a szolgáltatást Web API alapokra

helyezzem, ezáltal is csökkentve a hálózaton átvitt adat mennyiségét.

Látható tehát, hogy bőven adódnak fejlesztési lehetőségek, amiknek a kiaknázása

egy még szerethetőbb terméket hozhat létre.

Page 67: BSc Thesis - SimpleXpense

67

Irodalomjegyzék

[1] Jon Galloway, Phil Haack, Brad Wilson, K. Scott Allen: Professional ASP.NET

MVC 4

[2] ASP.NET: Single Page Application, http://www.asp.net/single-page-application

(2014. április)

[3] ASP.NET: Web Pages, http://www.asp.net/web-pages (2014. április)

[4] ASP.NET: Web Forms, http://www.asp.net/web-forms (2014. április)

[5] ASP.NET: MVC, http://www.asp.net/mvc (2014. április)

[6] ASP.NET: SignalR, http://www.asp.net/signalr (2014. április)

[7] Regius Kornél: ASP.NET MVC 4+, Szöveg verzió: V1.0.0827,

http://bit.ly/mvc4plusc (2014. március)

[8] Kovács Ferenc: Adatvezérelt alkalmazások fejlesztése előadás jegyzet (BME,

AUT, 2013)

[9] CodeProject, ASP.NET MVC 4 - Part [1] – Introduction,

http://www.codeproject.com/Articles/470107/ASP-NET-MVC-Part-Introduction

(2014. március)

[10] Danny Dover: Search Engine Optimization (SEO) Secrets, 1st edition (2011)

[11] CodeProject, Marla Sukesh: WebForms vs. MVC,

http://www.codeproject.com/Articles/528117/WebForms-vs-MVC (2014. május)

[12] Twitter Bootstrap v2.3.2, http://getbootstrap.com/2.3.2/ (2014. május)

[13] TwitterBootstrapMVC, https://www.twitterbootstrapmvc.com/ (2014. április)

[14] Telerik Kendo UI, http://www.telerik.com/kendo-ui (2014. május)

[15] Albert István, Fekete Krisztián: Windows Phone alapú szoftverfejlesztés előadás

jegyzet (BME, AUT, 2013)

[16] Andy Wigley, Rob Tiffany: M5: Windows Phone 8 Application Lifecycle,

http://download.microsoft.com/download/8/8/E/88E56A15-50E6-42D0-A71A-

CCD5673425C4/S5%20WP8%20Application%20Lifecycle.pdf (2014. május)

[17] MSDN Blogs, Brandon Bray: Announcing the release of the .NET Framework for

Windows Phone 8,

http://blogs.msdn.com/b/dotnet/archive/2012/10/30/announcing-the-release-of-

the-net-framework-for-windows-phone-8.aspx (2014. május)

Page 68: BSc Thesis - SimpleXpense

68

[18] MSDN Blogs, Deepti Prakash: Compile in the Cloud with WP8,

http://blogs.msdn.com/b/msgulfcommunity/archive/2013/03/16/compile-in-the-

cloud-with-wp8.aspx (2014. május)

[19] GitHub, PropertyChanged.Fody, https://github.com/Fody/PropertyChanged

[20] CodePlex, Windows Phone Toolkit, http://phone.codeplex.com/

[21] CodePlex, AppBar Utils, http://appbarutils.codeplex.com/

[22] CodePlex, Coding4Fun Toolkit, https://coding4fun.codeplex.com/

[23] CodePlex, Windows Phone IsoStoreSpy, http://isostorespy.codeplex.com/

[24] Benedek Zoltán: Az újgenerációs .NET platform előadás jegyzet (BME, AUT,

2012)

[25] CodeProject, Praveen Kumar Katiyar: Understanding Contracts in WCF,

http://www.codeproject.com/Articles/664238/Understanding-Contracts-in-WCF

(2014. május)

[26] Roy Thomas Fielding: Architectural Styles and the Design of Network-based

Software Architectures, Doctoral dissertation, Chapter 5 (University of California,

Irvine, 2000), http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

[27] Reiter István: ASP.NET MVC Web API (2013), https://devportal.hu/download/E-

bookok/ASP.NET%20MVC%20Web%20API.pdf (2014. május)

[28] MSDN, WCF and ASP.NET Web API, http://msdn.microsoft.com/en-

us/library/jj823172(v=vs.110).aspx (2014. május)

[29] MSDN, Windows Communication Foundation, http://msdn.microsoft.com/en-

us/library/dd456779(v=vs.110).aspx (2014. május)

[30] Julia Lerman: Programming Entity Framework, 2nd Edition (2010)

[31] ITWorld, Matthew Mombrea: 3 reasons to use code first design with Entity

Framework, http://www.itworld.com/development/405005/3-reasons-use-code-

first-design-entity-framework (2014. április)

[32] MSDN, Loading Related Entities, http://msdn.microsoft.com/en-

us/data/jj574232.aspx (2014. április)

[33] MSDN, Dispose Pattern, http://msdn.microsoft.com/en-

us/library/b1yfkh5e(v=vs.110).aspx (2014. április)

[34] CodePlex, Stephen Cleary: Nito AsyncEx, http://nitoasyncex.codeplex.com/

(2014. április)

[35] Stephen Cleary: Concurrency in C# Cookbook

[36] jQuery, http://jquery.com/

Page 69: BSc Thesis - SimpleXpense

69

Függelék: Kliensek egyéb funkciói

Jelen függelékben a dolgozatból kimaradt ábrák találhatók a mobil, valamint web

kliens felületéről, melyeken a nem részletezett funkciókat tekinthetjük meg.

Az 5-1. ábra a mobil kliens egyéb oldalait mutatja, magyar nyelvi beállítás mellett:

5-1. ábra: Valuta átváltás, új kategória és a tranzakció részletező oldalak (WP8)

Az alábbi képeken a web kliens nem ismertetett funkciónak a felületét láthatjuk:

5-2. ábra: Új kategória létrehozása (web)

Page 70: BSc Thesis - SimpleXpense

70

5-3. ábra: Valuta átváltás (web)

5-4. ábra: Felhasználói beállítások (web)

5-5. ábra: Áttekintő lista részlete (web)