Upload
others
View
11
Download
0
Embed Size (px)
Citation preview
Rok Povodnik
RAZVOJ IN TESTIRANJE SPLETNIH
APLIKACIJ Z UPORABO MVC 4 BETA
Diplomsko delo
Maribor, september 2012
RAZVOJ IN TESTIRANJE SPLETNIH APLIKACIJ Z
UPORABO MVC 4 BETA
Diplomsko delo
Študent: Rok Povodnik
Študijski program: Visokošolski strokovni študijski program prve stopnje
Informatika in tehnologije komuniciranja
Smer: Razvoj informacijskih sistemov
Mentor: viš. pred. mag. Boštjan Kežmah
i
ii
ZAHVALA
Za izkazano zaupanje, pripravljenost za
sodelovanje in nesebično pomoč pri usmerjanju in
nastajanju diplomskega dela se zahvaljujem
svojemu mentorju viš. pred. mag. Boštjanu
Kežmahu.
Iskreno se zahvaljujem tudi moji boljši polovici
Nataliji za moralno podporo ter očetu in materi za
vso podporo in finančno pomoč pri študiju.
Zahvaljujem se tudi vsem ostalim, ki so me v času
študija in pri nastajanju tega diplomskega dela
vodili, pomagali, podpirali in mi stali ob strani.
iii
Razvoj in testiranje spletnih aplikacij z uporabo
ASP.NET MVC 4 beta
Ključne besede: Microsoft, ASP.NET, MVC 4, Visual Studio, princip obračanja
odvisnosti, injiciranje odvisnosti, obračanje nadzora, IOC zabojnik, test enote, testno
usmerjen razvoj, šibka sklopljenost aplikacijskih komponent
UDK: 659.2:004+004.738.5(043.2)
Povzetek
V diplomskem delu je predstavljen razvoj spletnih aplikacij z uporabo ASP.NET MVC 4
beta. Predstavljene so tudi arhitektura in prednosti vzorca MVC ter določene novosti, ki
jih prinaša ASP.NET MVC 4. V nadaljevanju je prikazan koncept gradnje šibko sklopljenih
aplikacijskih komponent z uporabo principa obračanja odvisnosti in nadzora.
Predstavljena je tehnika injiciranja odvisnosti s pomočjo zabojnikov, katera je v
nadaljevanju naloge na kratko predstavljena in medsebojno primerjana. Prikazano je kako
poteka testiranje aplikacij z uporabo testov enot in kakšne so smernice testno usmerjenega
razvoja. Naloga je zaokrožena z izgradnjo aplikacije s pomočjo katere so zgoraj omenjeni
pojmi dejansko udejanjeni.
iv
Development and testing of web applications using
MVC 4 beta
Key words: Microsoft, ASP.NET, MVC 4, Visual, Studio, Dependency Inversion
Principle, Dependency Injection, Inversion of Control, IOC container, unit test, test driven
development, weakly coupled application components
UDK: 659.2:004+004.738.5(043.2)
Abstract
The thesis presents the development of web applications using ASP.NET MVC 4 beta. It
introduces MVC architecture, it's advantages and certain new features brought by
ASP.NET MVC 4.The following chapters focus on the concept of building weakly coupled
application components using the Dependency Inversion Principle and Inversion of
Control followed by a presentation of the technique that uses Dependency Injection with
the help of DI containers which was hereinafter briefly introduced and mutually compared.
It is demonstrated how to conduct testing of applications using unit tests and what are the
guidelines of a test driven development. The thesis is rounded up with the construction of
an application where the above mentioned concepts are actually put into practice.
v
KAZALO VSEBINE
1 UVOD ........................................................................................................................... 1
1.1 OPREDELITEV PODROČJA IN PROBLEMA ...................................................................... 1
1.2 PREDPOSTAVKE IN OMEJITVE DIPLOMSKEGA DELA ..................................................... 1
1.3 PREDSTAVITEV OSNOVNIH METOD DELA..................................................................... 1
1.4 STRUKTURA DIPLOMSKEGA DELA ............................................................................... 1
2 ARHITEKTURA MODEL-VIEW-CONTROLLER ............................................... 4
2.1 ZGODOVINA MVC ...................................................................................................... 4
2.2 SPOZNAVANJE DOMENSKEGA MODELA ....................................................................... 4
2.3 IMPLEMENTACIJA MVC VZORCA V ASP.NET MVC .................................................. 5
2.4 PREDNOSTI ASP.NET MVC ...................................................................................... 6
2.4.1 Razširljivost ....................................................................................................... 6
2.4.2 Strog nadzor nad HTML in HTTP ..................................................................... 6
2.4.3 Testabilnost ........................................................................................................ 7
2.4.4 Zmogljiv usmerjevalni sistem ............................................................................ 7
3 NOVOSTI V MVC 4 ................................................................................................... 8
3.1 PRIKAZOVANJE POGLEDOV GLEDE NA NAPRAVO ........................................................ 8
3.2 ZDRUŽEVANJE IN MINIFIKACIJA JAVASCRIPT IN CSS DATOTEK ................................ 11
3.3 IZBOLJŠAVE RAZOR POGONA .................................................................................... 12
3.3.1 Samodejno razreševanje absolutnih URL povezav .......................................... 12
3.3.2 Pogojni atributi ............................................................................................... 13
3.4 WEB API .................................................................................................................. 14
4 GRADNJA ŠIBKO SKLOPLJENIH APLIKACIJSKIH KOMPONENT .......... 17
4.1 PRINCIP OBRAČANJA ODVISNOSTI (DEPENDENCY INVERSION PRINCIPLE) ................ 17
4.2 PROBLEM: TESNA SKLOPLJENOST ............................................................................. 23
4.3 OBRAČANJE NADZORA (INVERSION OF CONTROL) .................................................... 26
vi
4.3.1 Obračanje vmesnika (Interface Inversion) ...................................................... 26
4.3.2 Obračanje toka ................................................................................................ 28
4.3.3 Nadzor nad ustvarjanjem-obračanje ustvarjanja odvisnosti .......................... 30
4.4 INJICIRANJE ODVISNOSTI (DEPENDENCY INJECTION) ................................................ 32
4.4.1 Injiciranje preko konstruktorja ........................................................................ 33
4.4.2 Injiciranje preko lastnosti ................................................................................ 34
4.4.3 Injiciranje preko vmesnika .............................................................................. 34
4.5 PREGLED POJMOV POVEZANIH Z OBRAČANJEM ODVISNOSTI ..................................... 35
4.6 IOC ZABOJNIKI ......................................................................................................... 36
4.6.1 Castle Windsor ................................................................................................ 39
4.6.2 Unity ................................................................................................................ 42
4.6.3 Structure Map .................................................................................................. 45
4.6.4 Ninject .............................................................................................................. 48
4.6.5 Medsebojna primerjava zabojnikov................................................................. 50
5 TESTIRANJE APLIKACIJ ..................................................................................... 52
5.1 TESTNO USMERJEN RAZVOJ ...................................................................................... 52
5.2 TDD KOT RAZVOJNA PRAKSA ................................................................................... 53
5.3 TESTI ENOT ............................................................................................................... 55
5.3.1 Mocking (oponašalni) objekti .......................................................................... 56
5.3.2 Moq .................................................................................................................. 58
5.4 TESTIRANJE JAVASCRIPTA ....................................................................................... 63
5.4.1 qUnit testirno ogrodje ..................................................................................... 63
6 PRIMER RAZVOJA SPLETNE APLIKACIJE V ASP.NET MVC 4 ................ 68
6.1 VODIČ DO RAZVOJA ENOSTAVNE SPLETNE APLIKACIJE ............................................. 68
6.2 SPLETNI PORTAL EVROPSKI PLAČILNI NALOG ........................................................... 80
6.2.1 Predstavitev projekta ....................................................................................... 80
6.2.2 Podrobnosti izdelave projekta ......................................................................... 82
vii
6.3 KORISTNI PRISTOPI IN NAPOTKI ZA IZGRADNJO MODERNIH ASP.NET MVC 4
APLIKACIJ ......................................................................................................................... 90
7 SKLEP ........................................................................................................................ 95
SEZNAM UPORABLJENIH VIROV ............................................................................. 96
viii
KAZALO SLIK
SLIKA 2.1: DELOVANJE MVC APLIKACIJE. ............................................................................. 5
SLIKA 3.1: MOBILNA VERZIJA POSTAVITVE SPLETNE STRANI .................................................. 9
SLIKA 3.2: NAMIZNA VERZIJA POGLEDA PRIKAZANA NA NAMIZNEM RAČUNALNIKU .............. 9
SLIKA 3.3: MOBILNA VERZIJA POGLEDA PRIKAZANA NA ANDROID NAPRAVI ........................ 10
SLIKA 3.4: USTVARJANJE NOVEGA PRIKAZOVALNEGA NAČINA ZA INTERNET EXPLORER 9 .. 11
SLIKA 3.5: STARI NAČIN NASLAVLJANJA DATOTEK ............................................................... 12
SLIKA 3.6: NOVI NAČIN NASLAVLJANJA DATOTEK V BETA VERZIJI ....................................... 12
SLIKA 3.7: NAJNOVEJŠI NAČIN NASLAVLJANJA DATOTEK V RC RAZLIČICI ........................... 12
SLIKA 3.8: DEFINICIJA LASTNEGA ZDRUŽENJA JAVASCRIPT DATOTEK ................................. 12
SLIKA 3.9: STARI NAČIN NASLAVLJANJA VIROV S POMOČJO POMOŽNE METODE CONTENT ... 13
SLIKA 3.10: NOV NAČIN NASLAVLJANJA VIROV .................................................................... 13
SLIKA 3.11: PRIMER VSTAVLJANJA POGOJNEGA ATRIBUTA V ELEMENT BODY ...................... 14
SLIKA 3.12: POENOSTAVLJEN NAČIN VSTAVLJANJA POGOJNEGA ATRIBUTA V ELEMENT BODY
..................................................................................................................................... 14
SLIKA 3.13: PRIMER USTVARJANJA WCT SPLETNE STORITVE............................................... 15
SLIKA 3.14: PRIMER USTVARJANJA WEB API STORITVE ....................................................... 16
SLIKA 3.15:DELOVANJE WEB API STORITVE ....................................................................... 16
SLIKA 4.1: PRENOSNE POLNILNE NAPRAVE BREZ SKUPNEGA VMESNIKA ZA POLNJENJE ........ 18
SLIKA 4.2: ARHITEKTURA RAZREDOV APLIKACIJE BREZ OBRAČANJA ODVISNOSTI ............... 19
SLIKA 4.3: DIAGRAM Z OBRNJENIMI ODVISNOSTMI ............................................................... 20
SLIKA 4.4: PRIMER ENOSTAVNEGA PROGRAMA, KI BERE IN ZAPISUJE ZNAKE REALIZIRANEGA
S POMOČJO OBRAČANJA ODVISNOSTI ............................................................................ 21
SLIKA 4.5: PRIMER PROGRAMA GUMB SVETILKA REALIZIRANEGA Z OBRAČANJEM ODVISNOSTI
..................................................................................................................................... 22
SLIKA 4.6: IZVAJANJE PROGRAMA V PRAKSI ......................................................................... 23
SLIKA 4.7: PROBLEM TESNE SKLOPLJENOSTI ........................................................................ 24
ix
SLIKA 4.8: PRIMER REALIZACIJE ŠIBKE SKLOPLJENOSTI S POMOČJO IOC OGRODJA .............. 25
SLIKA 4.9: NEPRAVILNA UPORABA OBRAČANJA VMESNIKA .................................................. 27
SLIKA 4.10: PRAVILNA UPORABA OBRAČANJA VMESNIKA - OBRNJENA ODVISNOST .............. 28
SLIKA 4.11: PRIMER PROCEDURALNEGA TOKA PROGRAMA .................................................. 29
SLIKA 4.12: PRIMER APLIKACIJE Z OBRNJENIM TOKOM ......................................................... 30
SLIKA 4.13: PODVAJANJE BLOKA PROGRAMSKE KODE .......................................................... 32
SLIKA 4.14: DIAGRAM INJICIRANJA ODVISNOSTI .................................................................. 33
SLIKA 4.15: INJICIRANJE ODVISNOSTI PREKO KONSTRUKTORJA ............................................ 34
SLIKA 4.16: INJICIRANJE ODVISNOSTI PREKO LASTNOSTI ...................................................... 34
SLIKA 4.17: INJICIRANJE ODVISNOSTI PREKO VMESNIKA ...................................................... 35
SLIKA 4.18: PREGLED POJMOV POVEZANIH Z OBRAČANJEM ODVISNOSTI .............................. 36
SLIKA 4.19: RAZREDNI DIAGRAM IOC ZABOJNIKA ............................................................... 37
SLIKA 4.20: IZVEDBA RAZREDA ZABOJNIK ........................................................................... 38
SLIKA 4.21: UPORABA ZABOJNIKA V PRAKSI ........................................................................ 39
SLIKA 4. 22: UPORABA ZABOJNIKA CASTLE WINDSOR ......................................................... 40
SLIKA 4.23: SKLICEVANJE NA EDINSTVENO POIMENOVANO REGISTRIRANO PRESLIKAVO ..... 40
SLIKA 4.24: EKSPLICITNO NAVAJANJE POIMENOVANIH ODVISNOSTI IN ROČNO NAVAJANJE
UPORABLJENIH ODVISNOSTI .......................................................................................... 41
SLIKA 4.25: PRIMER NAMESTITVENEGA PAKETA .................................................................. 41
SLIKA 4.26: PRIMER UPORABE PREHODNEGA ŽIVLJENJSKEGA CIKLA .................................... 42
SLIKA 4.27: UPORABA ZABOJNIKA UNITY ............................................................................ 43
SLIKA 4.28: ROČNO SPREMINJANJE POVEZOVANJA TIPOV ..................................................... 43
SLIKA 4.29: PRIMER RAZŠIRITVE .......................................................................................... 44
SLIKA 4.30: EKSPLICITNO NAVAJANJE POIMENOVANIH ODVISNOSTI IN ROČNO NAVAJANJE
UPORABLJENIH ODVISNOSTI V ZABOJNIKU UNITY ......................................................... 44
SLIKA 4.31: UPRAVLJANJE ŽIVLJENJSKEGA CIKLA REGISTRIRANIH TIPOV............................. 45
SLIKA 4.32: DELOVANJE ZABOJNIKA STRUCTURE MAP ........................................................ 46
SLIKA 4.33: PRIMER RAZŠIRITVENEGA RAZREDA .................................................................. 46
x
SLIKA 4.34: EKSPLICITNO NAVAJANJE POIMENOVANIH ODVISNOSTI IN ROČNO NAVAJANJE
UPORABLJENIH ODVISNOSTI V ZABOJNIKU STRUCTURE MAP ........................................ 47
SLIKA 4.35: UPRAVLJANJE ŽIVLJENJSKEGA CIKLA REGISTRIRANIH TIPOV PRI STRUCTURE
MAP .............................................................................................................................. 48
SLIKA 4.36: UPORABA ZABOJNIKA NINJECT ......................................................................... 49
SLIKA 4.37: PRIMER NINJECT MODULA ................................................................................ 49
SLIKA 4.38: EKSPLICITNO NAVAJANJE POIMENOVANIH INSTANC ISTEGA TIPA S POMOČJO
IMENA IN POSEBNEGA RAZREDA V VLOGI ATRIBUTA ..................................................... 50
SLIKA 4.39: UPRAVLJANJE ŽIVLJENJSKEGA CIKLA REGISTRIRANIH TIPOV PRI NINJECT. ........ 50
SLIKA 5.1: DIAGRAM POTEKA RAZVOJA PROGRAMSKE OPREME S POMOČJO TFD RAZVOJA .. 54
SLIKA 5.2: PRIMER RAZREDA, KI SIMULIRA DOLGO TRAJAJOČO OPERACIJO .......................... 58
SLIKA 5.3: TESTIRANJE DOLGO TRAJAJOČE METODE ............................................................. 59
SLIKA 5.4: PRIMER TESTA Z UPORABO MOQ ORGODJA .......................................................... 60
SLIKA 5.5: PRIMER TESTA Z UPORABO MOQ OGRODJA IN UPORABE POSEBNEGA KONSTRUKTA
ISANY ........................................................................................................................... 61
SLIKA 5.6: KONFIGURIRANJE MOQ OGRODJA, DA PRI DOLOČENIH POGOJIH PROŽI IZJEMO .... 62
SLIKA 5.7: ARRANGE ACT ASSERT VZOREC ......................................................................... 62
SLIKA 5.8: STRUKTURA QUNIT PROJEKTA ............................................................................ 64
SLIKA 5.9: PREPROSTA LOGIKA TRANSAKCIJSKEGA RAČUNA NAPISANA V JAVASCRIPT-U .... 64
SLIKA 5.10: OKVIR V KATEREM SE IZVAJAJO QUNIT TESTI ENOT .......................................... 65
SLIKA 5.11: IZDELANI QUNIT TESTI ENOT ............................................................................. 66
SLIKA 5.12: REZULTATI TESTOV ENOT .................................................................................. 67
SLIKA 6.1: PODATKOVNA BAZA SPLETNE APLIKACIJE ........................................................... 68
SLIKA 6.2: ORGANIZACIJA PROJEKTOV V SPLETNI APLIKACIJI ............................................... 69
SLIKA 6.3: IZGLED POGLEDA ................................................................................................ 70
SLIKA 6.4: USTVARJANJE REPOZITORIJA IZDELKOV NA DOMENSKEM NIVOJU ....................... 71
SLIKA 6.5: LOGIKA PRIDOBIVANJA IZDELKOV NA DOMENSKEM NIVOJU ................................ 71
SLIKA 6.6: SPREMENJEN KRMILNIK PRILAGOJEN INJICIRANJU ODVISNOSTI PREKO
KONSTRUKTORJA .......................................................................................................... 72
xi
SLIKA 6.7: IMPLEMENTACIJA IZDELEK STORITVE .................................................................. 73
SLIKA 6.8: KONKRETNI REPOZITORIJ IZDELKOV IMPLEMENTIRAN NA NIVOJU DOSTOPA DO
PODATKOV .................................................................................................................... 74
SLIKA 6.9: ASOCIIRANJE PRESLIKAV V ZABOJNIKU ............................................................... 74
SLIKA 6.10: IZGLED STRANI, KO JE VANJO PRIJAVLJEN NAVADEN UPORABNIK ...................... 75
SLIKA 6.11: UVELJAVLJEN 10% POPUST ZARADI UPORABNIKA S STATUSOM ZVESTEGA KUPCA
..................................................................................................................................... 76
SLIKA 6.12: DIAGRAM POTEKA, KI PRIKAZUJE POTEK INTERAKCIJ V APLIKACIJI PRI
DOSTOPANJU DO INDEX POGLEDA IN POSLEDIČNEM PRIKAZU ZNIŽANIH IZDELKOV ....... 77
SLIKA 6.13: STRUKTURA IN PRIKAZ MEDSEBOJNIH ODVISNOSTI V APLIKACIJI ...................... 78
SLIKA 6.14: PRIMER LAMBDA IZRAZA................................................................................... 78
SLIKA 6.15: IMPLEMENTACIJA METODE, KI PRIDOBI UPORABNIKA GLEDE NA DOLOČEN
KRITERIJ ....................................................................................................................... 79
SLIKA 6.16: RAZRED, KI OMOGOČA PRETVORBO DREVES IZRAZOV ....................................... 79
SLIKA 6.17: PRETVORBA DREVESA IZRAZOV, DA LAHKO DELUJE NAD UPORABNIKOM NIVOJA
DOSTOPA DO PODATKOV ............................................................................................... 80
SLIKA 6.18: PRIMER TESTIRANJA S POMOČJO AUTOFIXTURE ................................................ 80
SLIKA 6.19: EVROPSKI PLAČILNI NALOG, OBRAZEC E ........................................................... 81
SLIKA 6.20: IZDELAN ENTITETNI MODEL PORTALA ............................................................... 83
SLIKA 6.21: RAZREDNI DIAGRAM REPOZITORIJEV ................................................................ 84
SLIKA 6.22: ENOTA DELA ..................................................................................................... 85
SLIKA 6.23: NAPAKA PRI PRIJAVI V PORTAL ZARADI UPORABE NAPAČNEGA DIGITALNEGA
POTRDILA...................................................................................................................... 86
SLIKA 6.24: ADMINISTRACIJA UPORABNIKOV ....................................................................... 87
SLIKA 6.25: ZADNJI KORAK ČAROVNIKA, KI OMOGOČA PREDOGLED PLAČILNEGA NALOGA
PRED DOKONČNO ODDAJO ............................................................................................. 88
SLIKA 6.26: SODNI ZAHTEVKI VEZANI NA SODNIKA .............................................................. 89
SLIKA 6.27: PODROBNOSTI O IZBRANEMU SODNEMU ZAHTEVKU .......................................... 89
SLIKA 6.28: PRENOS PDF DATOTEKE IZ PORTALA ................................................................ 90
xii
KAZALO TABEL
TABELA 1: PREDNOSTI PRIDOBLJENE Z UPORABO ŠIBKE SKLOPLJENOSTI .............................. 25
TABELA 2: MEDSEBOJNA PRIMERJAVA ZABOJNIKOV ............................................................ 51
TABELA 3: KORISTNI PRISTOPI, METODE IN NAPOTKI PRI IZGRADNJI MODERNIH APLIKACIJ. . 90
xiii
SEZNAM UPORABLJENIH KRATIC
API – Application programming interface
MVC – Model View Controller
DI – Dependency Injection
DIP – Dependency Inversion Principle
GUI – Graphical User Interface
IOC – Inversion of Control
POCO – Plain Old Common Language Runtime Object
SOAP – Simple Object Access Protocol
TDD – Test Driven Development
WCF– Windows Communication Foundation
WPF– Windows Presentation Foundation
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 1
1 UVOD
1.1 Opredelitev področja in problema
Pri razvoju spletnih aplikacij se dostikrat zanemarja arhitektura aplikacij. Pri majhnih
aplikacijah dobra arhitektura še nekako ne prikaže svojih prednosti in izredne uporabnosti.
Vendar, ko se lotimo obsežnejšega in kompleksnejšega projekta, katerega namen je
obstajati mnogo let, je dobra arhitektura, testiranje enot ter šibka sklopljenost komponent
aplikacije bistvenega pomena. Dosti razvijalcev zanemarja ali premalo posveča pozornost
dobri arhitekturi ter testom enot zaradi povečanja časa in stroškov pri razvoju storitev. V
diplomskem delu smo obravnavali pomembnost izvajanja dobre aplikacijske arhitekture ter
testiranja enot, kar omogoča robustnejše in prilagodljivejše izvedbe aplikacij, ki lažje
kljubujejo zobu časa in spremenjenim zahtevam uporabnikov.
1.2 Predpostavke in omejitve diplomskega dela
Pri diplomskem delu smo se omejili na razvijanje ASP.NET MVC 4 aplikacij v
programskem jeziku C#. Pri praktičnem primeru izgradnje aplikacije smo uporabljali
knjižnico Moq ter injicirno ogrodje Ninject. Za izgradnjo, manipulacijo in dostop do
podatkovne baze smo uporabljali Entity Framework Model-First pristop. Pri testiranju smo
se omejili na teste enot ter predstavili smernico AAA (Arrange Act Assert), ki naredi teste
enot jasnejše in lažje berljive. Za testiranje smo uporabljali ogrodje xUnit.
1.3 Predstavitev osnovnih metod dela
V diplomskem delu smo uporabili deskriptivni pristop. V okviru deskriptivnega pristopa
smo uporabili:
metodo deskripcije, s katero smo opisali pojme ter teorijo in
metodo komparacije, s katero smo primerjali teorije in dela različnih avtorjev.
1.4 Struktura diplomskega dela
Diplomsko delo je sestavljeno iz sedmih delov.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 2
V diplomskem delu smo predstavili razvoj modernih šibko sklopljenih spletnih aplikacij z
uporabo ASP.NET MVC 4 beta, novosti, ki jih prinaša nova verzija MVC ogrodja, kot je
Web API, DI zabojnike Ninject, Castle Windsor, Unity in Structure Map. Predstavili smo
napotke in potek izdelave testov enot ter na primeru, v obliki vodiča, prikazali gradnjo
šibko sklopljene spletne aplikacije.
V drugem poglavju smo predstavili arhitekturo MVC vzorca in zgodovino njegovega
nastanka. Spoznali smo se z domenskim modelom in podrobneje prikazali implementacijo
MVC vzorca v ASP.NET MVC ter prednosti, ki jih prinaša njegova uporaba.
Nadaljnje smo v tretjem poglavju predstavili novosti, ki jih prinaša najnovejša različica
ASP.NET MVC, kot so prikazovanje pogledov specifičnih glede na napravo, združevanje
in minifikacija JavaScript in CSS datotek, manjše, ampak opazne izboljšave Razor pogona
ter popolnoma novo ogrodje Web API, ki omogoča ustvarjanje enostavnih spletnih HTTP
storitev.
V četrtem poglavju smo predstavili gradnjo šibko sklopljenih aplikacijskih komponent.
Podrobneje smo predstavili princip obračanja odvisnosti, načrtovalski vzorec obračanje
nadzora in različne dejanske implementacije obračanja nadzora, kot so obračanje
vmesnika, toka in ustvarjanja odvisnosti. Predstavili smo injiciranje odvisnosti, ki je
podmnožica obračanja ustvarjanja odvisnosti. Na praktičnem primeru smo prikazali tri
možne načine injiciranja odvisnosti. Ti so injiciranje preko konstruktorja, lastnosti in
vmesnika. Proti koncu poglavja smo pregledali, jasno razčlenili in ločili med seboj zelo
podobne pojme in koncepte, ki so povezani z obračanjem odvisnosti. Kot zanimivost smo
prikazali štiri najpopularnejše DI zabojnike in jih na kratko predstavili in medsebojno
primerjali.
V naslednjem poglavju smo predstavili testiranje aplikacij, koncept testno usmerjenega
razvoja ter dobre razvojne prakse, ki jih s seboj prinaša. Natančneje smo predstavili teste
enot, njihove značilnosti, prednosti in smernice, ki jih je potrebno upoštevati, če želimo
pisati dobre teste enot. Predstavili smo Mock (oponašalne) objekte, ogrodje Moq in
njihovo vlogo v kombinaciji z testi enot. Na koncu poglavja smo prikazali potek in način
testiranja JavaScript kode z uporabo testirnega ogrodja qUnit.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 3
V predzadnjem poglavju smo, v obliki vodiča, poskušali kar najenostavneje predstaviti
potek gradnje enostavne šibko sklopljene spletne aplikacije v ASP.NET MVC 4 in na
dejanskem izdelanem primeru dokazati prednosti, ki jih uporabljena arhitektura s seboj
prinaša. Dodatno smo predstavili ključne značilnosti in nekatere implementacijske
podrobnosti kompleksnejšega spletnega portala Evropski plačilni nalog, ki omogoča
spletno vročanje evropskih plačilnih nalogov (sodnih zahtevkov) v primeru raznih
denarnih terjatev.
Na koncu sledita še sklep in seznam uporabljenih virov.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 4
2 ARHITEKTURA MODEL-VIEW-CONTROLLER
2.1 Zgodovina MVC
Pojem Model View Controller (MVC) (model pogled krmilnik) je v uporabi od konca 70-
tih let prejšnjega stoletja pri projektu Smalltalk pri Xerox PARC, kjer je bila arhitektura
zasnovana kot način za boljšo organizacijo nekaterih prvih aplikacij z grafičnem
uporabniškem vmesnikom (GUI). Nekatere fine podrobnosti prvotnega MVC vzorca so
bile vezane specifično na Smalltalk, vendar je širši koncept vzorca še vedno veljaven in
uporaben za današnje aplikacije, še posebej za spletne aplikacije [1].
Interakcija z MVC aplikacijo sledi naravnemu ciklu uporabniških dejanj in posodobitev
pogleda, kjer se predpostavlja, da je pogled brez stanja. Ta način se lepo sklada s HTTP
zahtevami in odgovori, ki so podlaga spletnih aplikacij. Poleg tega MVC vsiljuje ločevanje
zadev-domenski model in krmilniška logika sta ločena od uporabniškega vmesnika. V
primeru spletne aplikacije to pomeni, da je HTML hranjen ločeno od ostalega dela
aplikacije, kar omogoča lažje in enostavnejše vzdrževanje ter testiranje. Krivec za ponovno
zanimanje in popularizacijo MVC arhitekture je Ruby on Rails, kateri je zgled pravega
MVC vzorca. Pozneje so se pojavila mnoga druga MVC ogrodja, katera so prikazala
prednosti MVC arhitekture. Eno izmed teh ogrodij je tudi ASP.NET MVC [1].
2.2 Spoznavanje domenskega modela
Domenski del je najpomembnejši del MVC aplikacije. Domenski model je ustvarjen s
pomočjo identificiranja entitet realnega sveta, operacij in veljavnostnih pravil, ki obstajajo
v področju ali dejavnosti, ki jih mora naša aplikacija podpirati, znana tudi kot domena. Iz
domene nato ustvarimo njeno programsko predstavitev, domenski model. V našem
primeru je domenski model množica programskih tipov (razredi, strukture ipd.), skupno
znanih kot domenski tipi. Domenske operacije predstavljajo metode opredeljene v
domenskih tipih, domenska pravila pa so izražena v logiki znotraj metod. Ko ustvarimo
instanco domenskega tipa za predstavitev specifičnega dela podatkov, ustvarimo domenski
objekt. Domenski modeli so po navadi obstojni z dolgo življenjsko dobo. Za doseganje
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 5
tega obstaja mnogo različnih načinov, najpogostejša izbira so še vedno relacijske
podatkovne baze [1].
Skratka, domenski model je edina enotna veljavna opredelitev poslovnih procesov in
podatkov znotraj naše aplikacije. Pristop domenskega modela poenostavi mnogo
problemov. Poslovna logika je ločena od ostalega dela aplikacije, zato je treba v primeru
manipulacije podatkov modela ali raznoraznega dodajanja novih procesov in pravil
spremeniti le domenski model [1].
2.3 Implementacija MVC vzorca v ASP.NET MVC
MVC aplikacija je sestavljena iz naslednjih delov [18]:
modela, ki vsebuje aplikacijsko logiko, katera ni vsebovana v pogledu in krmilniku,
to vključuje validacijsko in poslovno logiko ter logiko dostopa do podatkov;
pogleda, ki vsebuje HTML oznake ter logiko pogleda potrebno za ustvarjanje;
krmilnika, ki sodeluje in komunicira z modeli in pogledi ter tako nadzoruje tok
izvajanja aplikacije.
Dejanski krmilniki so pravzaprav C# razredi, ki dedujejo od razreda
System.Web.Mvc.Controller. Vsaka javna metoda krmilnika se imenuje akcijska metoda,
katera je povezana s prilagodljivim URL naslovom preko ASP.NET usmerjevalnega
sistema. Če je zahteva naslovljena na določen URL, kateri je povezan s specifično akcijsko
metodo, potem krmilnik izvede logiko opredeljeno znotraj akcijske metode, ki izvede
določene operacije nad domenskim modelom. Nazadnje krmilnik izbere pogled, kateri
prikaže rezultat uporabniku aplikacije (Slika 2.1) [1].
Slika 2.1: Delovanje MVC aplikacije.
Izvrševanje ločevanja zadev med modeli, pogledi in krmilniki se je izkazalo kot uporaben
način strukturiranja spletne aplikacije. Strogo ločevanje pogleda od preostanka spletne
aplikacije omogoča preoblikovanje videza aplikacije brez dotikanja središčne logike
aplikacije. Spletni oblikovalec lahko spreminja dizajn strani neodvisno od programerjev
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 6
zadolženih za poslovno logiko in logiko dostopa do podatkov. Ljudje z različnimi
veščinami in vlogami lahko spreminjajo različne dele aplikacije brez medsebojnih trenj.
Poleg tega se lahko v prihodnosti odločimo, da ponovno ustvarimo poglede naše aplikacije
s pomočjo druge tehnologije (npr. Silverlight namesto HTML). Kaj takšnega bi bilo težko
narediti, če bi imeli logiko pogleda prepleteno s preostankom aplikacijske logike [1].
Ločevanje krmilniške logike od preostale aplikacijske logike se je prav tako izkazalo kot
koristen način gradnje spletnih aplikacij. Pogosto je potrebno spremeniti način interakcije
uporabnika s spletno aplikacijo. Takrat, ko želimo spremeniti tok izvajanja aplikacije si
obenem ne želimo spreminjati logike pogleda in modela [1].
2.4 Prednosti ASP.NET MVC
Ključne prednosti ASP.NET so [18]:
odprtokodnost,
razširljivost,
strog nadzor nad HTML in HTTP,
testabilnost in
zmogljiv usmerjevalni sistem.
2.4.1 Razširljivost
MVC ogrodje je zgrajeno iz niza neodvisnih komponent v obliki vmesnika ali abstraktnega
razreda. Zaradi tega lahko enostavno zamenjamo posamezne komponente, kot so
usmerjevalni sistem, pogon pogleda (ASPX, Razor), tovarniška metoda za ustvarjanje
kontrolnikov in še mnoge druge z lastnimi alternativami [18].
2.4.2 Strog nadzor nad HTML in HTTP
ASP.NET MVC se zaveda pomembnosti ustvarjanja čistega označevalnega jezika
skladnega s standardi. Na voljo imamo HTML pomožne metode, ki ustvarjajo HTML
skladen s standardi. Poleg tega nas ogrodje poziva k izdelavi enostavnega, elegantnega
HTML zapisa oblikovanega s pomočjo CSS. V primeru, da želimo pogledu dodati
kompleksnejše elemente, kot so kaskadni meniji in razne animacije, lahko uporabimo
uradno podprto JavaScript knjižnico jQuery, ki naredi stran še elegantnejšo [18].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 7
2.4.3 Testabilnost
MVC arhitektura pomaga narediti spletne aplikacije testabilne in lahke za vzdrževanje
zaradi privzetega ločevanja aplikacijskih zadev v različne neodvisne dele programske
opreme. Vgrajena je podpora za testiranje enot. Dodan je tudi čarovnik za ustvarjanje
začetne šablone testov enot v obliki lastnega projekta s pomočjo Microsoftovega testnega
ogrodja Visual Studio Unit Testing Framework [18].
2.4.4 Zmogljiv usmerjevalni sistem
Današnji razvijalci spletnih aplikacij priznavajo velik pomen uporabi čistih URL naslovov.
URL naslov oblike »/App_v3/User/Page.aspx?action=show%20prop&prop_id=82742« je
popolnoma neberljiv in neprofesionalen v primerjavi z »/najem-stanovanj/ljubljana/1000-
mala-ulica«. Zakaj je poleg lažje berljivosti čista oblika URL-jev sploh pomembna?
Spletni iskalniki pripisujejo znatno težo ključnim besedam najdenim znotraj URL-ja.
Veliko večja verjetnost je, da se bo z uporabo iskalnega niza »najem-stanovanj Ljubljana«
med rezultati iskanja pojavil tudi slednji URL naslov. Če je URL naslov razumljiv se lahko
nekateri uporabniki usmerjajo po strani kar s tipkanjem v naslovno vrstico spletnega
brskalnika. Takšna oblika URL-jev nepotrebno ne izpostavlja tehničnih podrobnosti,
direktorija in datotečne strukture aplikacije celotnemu svetovnemu spletu tako, da
morebitne spremembe aplikacije (ob ustrezni usmerjevalni strategiji) ne vplivajo na URL
povezave. ASP.NET MVC uporablja System.Web.Routing razred za izgradnjo čistih URL-
jev, kar nam daje popoln nadzor nad preslikavo URL-jev na določene kontrolnike in
akcije, brez potrebe po skladnosti s katerimkoli vnaprej določenim vzorcem [18].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 8
3 NOVOSTI V MVC 4
3.1 Prikazovanje pogledov glede na napravo
Za omogočanje podpore prikazovanja strani na različnih vrstah naprav kot so pametni
telefoni, tablični in namizni računalniki so bili v preteklosti razvijalci primorani uporabljati
veliko število različnih modifikacij (trikov) na strani odjemalca. Uporabljali so posebne
CSS selektorje, katere so uspeli interpretirati samo določeni brskalniki, posebne JavaScript
skripte, katere so poskušale identificirati naprave na katerih se bodo pogledi prikazovali
ipd. Vsi ti triki so povzročili obilje medbrskalniških težav – različno prikazovanje istih
strani na različnih brskalnikih, kar je vodilo do nekonsistentnega dizajna strani. ASP.NET
MVC 4 ima za ta problem odlično rešitev: Prikazovalne načine (DisplayModes), ki se ne
zanašajo na modifikacije in trike na strani odjemalca.
Najlažji način za rešitev problema je uporaba vgrajene funkcije prikazovalnega načina
(DisplayMode), ki je namensko zasnovan za mobilne naprave. Prikazano na primeru.
Predstavljajmo si, da imamo narejen pogled z imenom Pogled.cshtml. Vse kar smo morali
naknadno storiti, je bilo ustvarjanje kopije pogleda, ki smo ga poimenovali
Pogled.Mobile.cshtml in vanj implementirali funkcionalnosti specifične za mobilne
naprave [5].
Pogleda se bosta pogojno prikazovala na sledeča načina [5]:
Pogled.cshtml bo prikazan na namiznih brskalnikih (Slika 3.2),
Pogled.Mobile.cshtml bo prikazan na mobilnih napravah (Slika 3.3).
Potrebno je poudariti, da se specifičen URL npr »/Domov/Pogled« preslika v enega izmed
zgoraj omenjenih pogledov glede na prikazovalno napravo, torej brez nepotrebnega
spreminjanja URL-ja (različnih URL-jev za namizno in mobilno verzijo spletne strani).
Isto funkcionalnost lahko uporabimo tudi pri delnih pogledih (partial views) in postavitvah
strani (Views\Shared\_layout.Mobile.cshtml) (Slika 3.1).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 9
Slika 3.1: Mobilna verzija postavitve spletne strani
Slika 3.2: Namizna verzija pogleda prikazana na namiznem računalniku
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 10
Slika 3.3: Mobilna verzija pogleda prikazana na Android napravi
Možno je ustvarjanje in dodajanje novih prikazovalnih načinov. V tem primeru želimo
dodati nov prikazovalni način za spletni brskalnik Internet Explorer 9 (Slika 3.4). Internet
Explorer 9 pošlje User-Agent glavo (niz znakov), ki vsebuje tekst »MSIE 9«. Ta pogoj
preverimo preko lastnosti ContextCondition (Func<HttpContetBase, bool>), ki kot vhodni
parameter sprejeme HttpContextBase in kot rezultat vrne boolean vrednost. Da novi
prikazovalni način deluje v praksi je potrebno pogledu dodati pripono ».IE9« tako, da ime
pogleda sestavimo v obliki »Pogled.IE9.cshtml« [5].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 11
Slika 3.4: Ustvarjanje novega prikazovalnega načina za Internet Explorer 9
3.2 Združevanje in minifikacija JavaScript in CSS datotek
Naslednja novost, ki se pojavlja v novi verziji MVC 4 ogrodja, je združevanje in
minifikacija JavaScript in CSS datotek. Dandanes spletne aplikacije vsebujejo mnogo
različnih statičnih sredstev večinoma JavaScript in CSS datotek. Za uspešen in pravilen
prikaz spletne strani mora brskalnik pred prikazom naložiti vsak statični vir posebej (kateri
je naveden v spletni strani). Za vsak posamezen vir se proži HTTP GET zahteva. Problem
je v tem, da vsaka HTTP terja določen časovni delež. Optimizacijo nalaganja strani
dosežemo najlažje, če posamezne statične vire združimo v eno datoteko in posledično
spremenimo množico zahtev v eno samo HTTP zahtevo.
Minifikacijo datotek bi lahko opisali na naslednji način [2]:
minifikacija je proces odprave nepotrebnih presledkov, koncev vrstic in
komentarjev iz programske kode (tudi CSS datotek), katerega posledica je
zmanjšanje velikosti minificiranih datotek in s tem izboljšanje hitrosti njihovega
prenosa do končnega uporabnika.
Na spodnjih slikah je viden stari (Slika 3.5) in novi način (Slika 3.6) naslavljanja *.js in
*.css datotek. V RC različici ogrodja je naslavljanje še enostavnejše (Slika 3.7). Imeni
»~/Content/themes/base/css« in »~/Scripts/js« tako nista več navidezni poti, ampak imena
posameznih združevanj. Uporaba združevanj shrani posamezne združene enote v
predpomnilnik brskalnika, kar naredi nalaganje strani ob naslednjem dostopu še hitrejše.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 12
Slika 3.5: Stari način naslavljanja datotek
Slika 3.6: Novi način naslavljanja datotek v beta verziji
Slika 3.7: Najnovejši način naslavljanja datotek v RC različici
Možna je tudi definicija lastnih združevanj kar s pomočjo C# kode v metodi
Application_Start (Slika 3.8).
Slika 3.8: Definicija lastnega združenja JavaScript datotek
3.3 Izboljšave Razor pogona
3.3.1 Samodejno razreševanje absolutnih URL povezav
Že od časa prve verzije ASP.NET je bilo na voljo posebno zaporedje sestavljeno iz dveh
znakov (~/), katerega pomen je predstavljal absoluten korenski URL naslov do spletne
aplikacije. Uporaba tega zaporedja znakov se šteje kot dobra praksa pri nameščanju
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 13
aplikacij, saj se izvorna koda programa (poti do virov in pogledov ipd.), v primeru
premeščanja aplikacije na drug strežnik oziroma lokacijo, ne rabi spreminjati [5].
V prvi verziji Razor pogona, ki je izšel z MVC 3, je bil edini možen način razreševanja
relativnih URL poti (predpona ~/) s pomočjo pomožne metode Url.Content (Slika 3.9).
Nov način naslavljanja virov (Slika 3.10) je veliko enostavnejši, preglednejši in predvsem
krajši kar naredi pogled bistveno manj zasičen [5].
Slika 3.9: Stari način naslavljanja virov s pomočjo pomožne metode Content
Slika 3.10: Nov način naslavljanja virov
3.3.2 Pogojni atributi
Pogojni atributi so atributi HTML elementov, ki so izpuščeni iz starševskega elementa, ko
je vrednost atributa null. Tipični primer takšnega problema je odločanje o prikazu
določenega atributa znotraj definicije div elementa, glede na to ali specifična vrednost
atributa obstaja. Takšen način dela je včasih povzročil grd skupek kode (Slika 3.11). Zapis
je bil nepregleden in težko vzdrževan. V novejši verziji Razor pogona je zaradi vgrajene
podpore za pogojne atribute vse skupaj veliko bolj pregledno in očem prijazno (Slika
3.12). Če je vrednost tipPisave null ali prazen niz, bo Razor v celoti zanemaril in izpustil
class atribut [5].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 14
Slika 3.11: Primer vstavljanja pogojnega atributa v element body
Slika 3.12: Poenostavljen način vstavljanja pogojnega atributa v element body
3.4 Web API
Web API je novo ogrodje, ki temelji na izkušnjah in vzorcih pridobljenih iz ASP.NET
MVC. Z uporabo enostavne krmilniške paradigme Web API omogoča ustvarjanje
enostavnih HTTP spletnih storitev z zelo malo kode in konfiguracije, ki lahko dosežejo
širok spekter odjemalcev, vključno z namiznimi računalniki, mobilnimi telefoni in
tablicami [5].
Lahko bi se vprašali, zakaj je sploh potrebno novo ogrodje za spletne storitve? Saj že kar
nekaj časa obstajajo razne SOAP in WCF storitve, ki že zagotavljajo storitveno
infrastrukturo. Ključne točke, ki govorijo v prid ogrodju Web API so [5]:
boljši, hitrejši in lažji način ustvarjanja spletnih storitev,
ustvarjanje novih spletnih storitev je lažje z uporabo Web API kot pa WCF,
velika verjetnost povečanja HTTP odjemalcev v prihodnosti,
temeljne HTTP zahteve kot so GET, POST, PUT in DELETE v večini primerov
zadoščajo za večino funkcionalnosti spletnih storitev.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 15
Način izdelave WCF storitve (Slika 3.13) je veliko bolj zapleten kot z uporabo Web API.
Pri WCF je vsaka spletna storitev opredeljena s pomočjo vmesnika, ki določa pogodbo.
Vsaka metoda označena z atributom OperationContract (operacijska pogodba) opredeljuje
operacijo v SOAP ovojnici WCF storitve. Razred, ki realizira vmesnik storitve,
implementira podrobno logiko delovanja storitve.
Slika 3.13: Primer ustvarjanja WCT spletne storitve
Mnogi razvijalci so si prizadevali za poenostavitev WCF HTTP spletnih storitev z uporabo
osnovnih ukazov HTTP protokola. Web API povzema koncept običajnega MVC krmilnika
in ga nadgrajuje za ustvarjanje enostavnega in produktivnega doživetja. Zaradi splošne
razširjenosti HTTP protokola v večini programskih okolij imamo zato na voljo osnovno
podporo spletnega komuniciranja preko HTTP protokola in s tem tudi rešen problem
interoperabilnosti [5].
Ista storitev, ki je bila pred tem ustvarjena s pomočjo WCF z Web API, izgleda veliko
enostavnejše (Slika 3.14). Za isto storitev smo porabili polovico manj vrstic programske
kode. Edini pogoj pri izdelavi je dedovanje od abstraktnega razreda APIController, kar
nam omogoča definiranje metod v vlogi operacij.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 16
Slika 3.14: Primer ustvarjanja Web API storitve
Spletno storitev lahko v praksi enostavno preizkusimo. V brskalnik vnesemo URL naslov
http://localhost:38304/api/values/50. Odgovor dobimo v serializirani (XML ali JSON
serializacija) obliki (Slika 3.15).
Slika 3.15:Delovanje Web API storitve
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 17
4 GRADNJA ŠIBKO SKLOPLJENIH APLIKACIJSKIH
KOMPONENT
4.1 Princip obračanja odvisnosti (Dependency Inversion Principle)
Pri običajni arhitekturi aplikacij so nižje nivojske komponente oziroma moduli izdelani s
tem namenom, da jih uporabljajo višje nivojski moduli, kar posledično privede do
izgradnje vedno bolj kompleksnih sistemov. V tem primeru so višje nivojski moduli
neposredno odvisni od nižje nivojskih modulov, v primeru, da želijo opraviti določeno
nalogo. Ta odvisnost od nižje nivojskih modulov omejuje ponovno uporabo določenih
komponent tako izdelane aplikacije [20].
Kot primer iz vsakdanjega življenja (Slika 4.1) si lahko predstavljamo razdelilnik, kot višje
nivojski modul ter prenosne polnilne naprave, kot nižje nivojske module. Takšne prenosne
polnilne naprave so npr. mobilni telefoni, tablični računalniki, kamere, fotoaparati ipd.
Vsaka izmed naštetih naprav definira svoj vmesnik, preko katerega se naprava polni
(micro, mini USB, ipd.) [6].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 18
Slika 4.1: Prenosne polnilne naprave brez skupnega vmesnika za polnjenje
Če bi želeli problem rešiti s pomočjo obračanja nadzora, bi vsaka izmed prenosnih
polnilnih naprav imela skupna vrata (skupen vmesnik), preko katerega bi jih lahko polnili.
Skupen vmesnik (napajalni kabel) pa bi bil definiran s strani višje nivojskega modula, torej
v našem primeru s strani razdelilnika. Teoretično gledano bi lahko z enim napajalnim
kablom, priklopljenim na razdelilnik, polnili katerokoli zgoraj omenjeno prenosno polnilno
napravo [6].
Prikaz arhitekture na razrednem nivoju
Na razrednem nivoju je arhitektura razredov aplikacije videti kot je prikazano na spodnji
sliki (Slika 4.2). Visokonivojski razred je odvisen od vmesnika, ki ga določa nizkonivojski
razred. Vmesnik tukaj ni mišljen kot programski konstrukt, temveč kot javno dostopni
člani nizkonivojskega razreda (javne metode, lastnosti), ki jih lahko uporablja
visokonivojski razred. Z drugimi besedami konceptualni vmesnik, ki ga uporablja
visokonivojski razred [6].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 19
Slika 4.2: Arhitektura razredov aplikacije brez obračanja odvisnosti
Do problema pride, ko imamo večje število nizkonivojskih razredov. V tem primeru mora
visokonivojski razred vsebovati switch ali if stavke, da je sposoben obvladovati razlike
med različnimi nizkonivojskimi razredi. Kot nizkonivojske razrede si lahko predstavljamo
različne podatkovne baze (SQL Server, MySQL, PostgreSQL, ipd.) ali bralnike različnih
tipov datotek (xml, binarne, tekstovne datoteke) do katerih dostopa višje nivojski razred,
ko želimo shraniti določene podatke. Vsakič, ko dodamo, odstranimo ali spremenimo
nizkonivojski razred, moramo spremeniti oziroma dodati določene podrobnosti
implementacije. Zaradi tega visokonivojskega razreda ne moremo ponovno uporabiti pri
drugih implementacijah.
Sedaj si poglejmo kako zgleda, razredni diagram, če odvisnosti obrnemo (Slika 4.3). Če si
diagram podrobneje ogledamo, smo vmesnik »prestavili« v višji nivo (modra črta na sliki
predstavlja mejo med plastmi – več nivojska arhitektura). Pri sodobnih aplikacijah
velikokrat uporabljamo več nivojsko arhitekturo, kot je npr. tri nivojska arhitektura, kjer
poznamo nivo odjemalca (uporabniški vmesnik), nivo poslovne logike in nivo dostopa do
podatkov (podatkovna baza). Visokonivojski razred v bistvu definira vmesnik, ki sedaj
obstaja v obliki vmesnika ali abstraktnega razreda. Pomemben je koncept, da nizkonivojski
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 20
razred ustreza oziroma je v skladu z vmesnikom, ki ga določa visokonivojski razred. Od
vmesnika je prav tako odvisen visokonivojski razred.
Slika 4.3: Diagram z obrnjenimi odvisnostmi
V primeru, da dodamo različne implementacije nizkonivojskih razredov, so te
implementacije še vedno odvisne od vmesnika. Pomembna stvar je, da dodajanje
nizkonivojskih razredov, ki so seveda skladni z vmesnikom, na nikakršen način ne vpliva
na visokonivojski razred. Zato torej spreminjanje logike v visokonivojskem razredu ni
potrebno. Sedaj smo končno prišli do našega cilja: ponovno uporabnega visokonivojskega
razreda [6].
Princip obračanja nadzora določa [20]:
visokonivojski moduli ne smejo biti odvisni od nizkonivojskih modulov, obojni
morajo biti odvisni od abstrakcij;
abstrakcije ne smejo biti odvisne od podrobnosti, temveč podrobnosti od abstrakcij.
Primer enostavnega programa, ki kopira znake
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 21
Predstavljajmo si primer enostavnega programa, katerega naloga je, da kopira znake (Slika
4.4), ki jih dobi iz bralca znakov ter prebrane znake zapiše na izbran medij. Zaradi
upoštevanja obračanja odvisnosti program enostavno razširimo z najrazličnejšimi bralci ter
zapisovalci. Naša aplikacija ima dva vmesnika:
bralca z metodo beri in
zapisovalca z metodo zapiši.
Slika 4.4: Primer enostavnega programa, ki bere in zapisuje znake realiziranega s pomočjo
obračanja odvisnosti
Zaradi vmesnikov, ki sta lahko realizirana kot abstraktna razreda ali vmesnika, lahko
dodajamo neomejeno število izpeljav raznih bralcev ter zapisovalcev. Zaradi abstrakcij
lahko razred Kopiraj neodvisno ponovno uporabimo kjerkoli drugje. Razred Kopiraj ne bo
nikoli odvisen od raznih izpeljav bralcev in zapisovalcev, temveč bodo vsi skupaj odvisni
le od abstrakcij realiziranih z vmesnikoma Bralec in Zapisovalec [3].
Za konec prikažimo uporabo obračanja odvisnosti na dejanskem izdelanem programu
(Slika 4.5). Ustvarili smo dve abstrakciji: vmesnik IButtonClient ter abstraktni razred
Button, kot zapoveduje princip obračanja odvisnosti. Vse podrobnosti izpeljanih in
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 22
realiziranih razredov so odvisne od abstrakcij. Razred Button ne pozna nikakršnih
podrobnosti o realizaciji mehanizma za odkrivanje stanj gumba niti o razredih kateri so
realizirani z vmesnikom IButtonClient. Vse podrobnosti so izolirane v konkretnih derivatih
- izpeljanih razredih. Zato lahko oblikujemo različne tipe naprav, kot so luči, sušilci za
lase, mešalniki ipd., ki enostavno dedujejo od vmesnika IButtonClient. Prav tako lahko
ustvarimo različne tipe gumbov in stikal. Naši razredi so zahvaljujoč abstrakcijam primerni
za ponovno uporabo, fleksibilni in robustni v primeru sprememb. Za konec si še poglejmo
dejanski rezultat zagona našega programa (Slika 4.6) [3].
Slika 4.5: Primer programa gumb svetilka realiziranega z obračanjem odvisnosti
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 23
Slika 4.6: Izvajanje programa v praksi
4.2 Problem: Tesna sklopljenost
Preden se poglobimo v pojem obračanje nadzora (Inversion of control) poskusimo najprej
razumeti problem, ki ga želimo odpraviti s pomočjo zgoraj omenjenega načela. Poskusimo
preučiti naslednji primer. Primer vsebuje dva razreda. Razreda Kupec in Naslov. Kupec
vsebuje objekt tipa razred Naslov. Največji problem s trenutno programsko kodo je tesna
sklopljenost med razredoma (Slika 4.7). Drugače povedano razred Kupec je odvisen od
razreda Naslov. Torej, če v razredu Naslov, zaradi kakršnegakoli razloga pride do
sprememb implementacije bo to prav tako vplivalo tudi na implementacijo in prevajanje
razreda Kupec [17].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 24
Slika 4.7: Problem tesne sklopljenosti
Konkretne težave zgoraj omenjenega pristopa razvijanja so:
največji problem je v tem, da razred Kupec nadzoruje ustvarjanje objekta Naslov;
razred Naslov je neposredno referenciran v razredu Kupec, kar privede do tesne
sklopljenosti med objektoma Naslov in Kupec;
razred Kupec se zaveda, da razredni tip Naslov obstaja. V primeru, da dodamo
nove vrste naslovov, kot sta domači ali službeni naslov pride do sprememb v
razredu Kupec, ker je razred Kupec prav tako izpostavljen dejanski implementaciji
razreda Naslov.
Torej, če se zaradi kakršnegakoli razloga objekt Naslov ne more ustvariti, bo celoten
razred Kupec prav tako pogorel pri lastni inicializaciji konstruktorja – instanca razreda
Kupec ne bo ustvarjena.
Rešitev
Sedaj ko poznamo problem, poskusimo razumeti tudi njegovo rešitev. Glavni problem
izhaja iz razreda Kupec, ki posledično v konstruktorju ustvarja objekt Naslov. Rešitev
našega problema je v tem, da prenesemo nadzor nad ustvarjanjem objekta Naslov iz
razreda Kupec k nečemu drugemu. Dejansko moramo obrniti nadzor na neko tretjo osebo.
Ta rešitev se imenuje obračanje nadzora (Inversion of control - IOC) (Slika 4.8) [17].
Prednosti pridobljene z uporabo šibke sklopljenosti so podane v tabeli 1 [13].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 25
Slika 4.8: Primer realizacije šibke sklopljenosti s pomočjo IOC ogrodja
Tabela 1: Prednosti pridobljene z uporabo šibke sklopljenosti
Prednost Opis Kdaj je koristno?
Pozna vezava Storitve so lahko
zamenjane z drugimi
storitvami.
Uporabno pri standardni programski opremi,
vendar nekoliko manj pri poslovnih
aplikacijah, kjer je razvojno okolje dobro
opredeljeno.
Razširljivost Programska koda se
lahko razširi in
ponovno uporabi na
načine, ki niso izrecno
predvideni.
Vedno uporabno.
Vzporedni
razvoj
Programsko kodo je
mogoče razvijati
vzporedno.
Koristno pri velikih, zapletenih aplikacijah in
ne preveč pri majhnih, preprostih aplikacijah.
Vzdrževalnost Razredi z jasno
opredeljenimi
odgovornostmi so
lažje vzdrževani.
Vedno uporabno.
Testabilnost Razredi so lahko
testirani s testi enot.
Uporabni samo, če uporabljamo teste enot.
IOC ogrodje
1. Ustvarjanje objekta Naslov
2. Vstavljanje objekta v razred Kupec
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 26
4.3 Obračanje nadzora (Inversion of Control)
Osnovno načelo obračanja nadzora si lahko najlažje predstavljamo kot naslednjo frazo:
»Ne kličite nas, mi bomo poklicali vas«. Obračanje nadzora si bolj kot ne lahko
predstavljamo kot visokonivojski načrtovalski vzorec, ki ga lahko uporabljano na različne
načine za obračanje različnih vrst nadzora. Ti nadzori so [7]:
nadzor nad vmesnikom med dvema sistemoma ali komponentama (kako
sistema, modula ali razreda, med seboj sodelujeta in si izmenjujeta podatke);
nadzor nad tokom aplikacije (kaj krmili tok programa, ta nadzor obrata se zgodi,
ko preidemo iz proceduralnega na dogodkovno usmerjeno programiranje) in
nadzor nad ustvarjanjem odvisnosti in vezavo tipov (prenos nadzora nad
dejanskim ustvarjanjem in izbiro odvisnosti tretji osebi-IOC zabojnikom, ki je
nevtralen od tipov in odvisnosti).
4.3.1 Obračanje vmesnika (Interface Inversion)
Poglejmo si primer uporabe neobrnjenih vmesnikov (Slika 4.9). Imamo razred Kenguru, ki
ima tri metode: Udari, Skoči in PojejSadje. Razred Kenguru samostojno (sam od sebe)
določa vmesnik, katerega je treba uporabiti za njegovo uporabo. Definiranje vmesnika
IKenguru je v trenutnem primeru nesmiselno. Razred BoksarskiDvoboj bi postal
prenasičen z raznimi odvisnostmi, kot sta IDejanZavec in IMikeTyson. Pravilna uporaba
obračanja vmesnika bi bila, če bi razred Kenguru prenehal neodvisno določati storitve,
katere ponuja in bi namesto tega postal ponudnik storitev katere želi koristiti neka tretja
oseba [7].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 27
Slika 4.9: Nepravilna uporaba obračanja vmesnika
Rešitev problema je v obračanju vmesnika (Slika 4.10). Želimo, da vmesnik (IBokser)
določa razred BoksarskiDvoboj katerega morajo upoštevati vsi naši »boksarji«. Tako lahko
znotraj razreda BoksarskiDvoboj enostavno uporabljamo vmesnik IBokser. Očitno je, da je
to resnično obračanje nadzora vmesnika. Običajno razred uporabniku za lastno uporabo
sam določa svoj vmesnik, v našem primeru pa vmesnik določa uporabnik razreda (razred
BoksarskiDvoboj). Vsak razred, ki želi biti ponudnik storitev (hoče biti boksar na
boksarskem dvoboju), mora implementirati vmesnik IBokser. Obrnili smo nadzor tako, da
je razred BoksarskiDvoboj odvisen od vmesnika IBokser ter prav tako vsi razredi, ki želijo
biti »boksarji« [7].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 28
Slika 4.10: Pravilna uporaba obračanja vmesnika - obrnjena odvisnost
4.3.2 Obračanje toka
Obračanje toka je enostavnejši način obračanja nadzora. Normalen tok programov je po
navadi proceduralen oziroma postopkovni. Najenostavnejši primer tega je konzolna
aplikacija (Slika 4.11) oziroma ukazna vrstica. Predstavljajmo si konzolno aplikacijo za
vnos in izpis študentov v/iz tekstovne datoteke. Izpiše se nam meni programa z izbirami, ki
so nam na voljo (vnos, izpis študenta). Po izbiri vnosa novega študenta nas program vpraša
po študentovem imenu in priimku, indeksu letniku študija, povprečni oceni in datumu
rojstva. Odgovore na vsako postavljeno vprašanje o novem študentu vpišemo v terminal,
potrdimo in v datoteko uspešno dodamo novega študenta. Naša aplikacija nadzoruje tok
interakcije z uporabnikom po točno določenem vrstnem redu glede na izbrano operacijo.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 29
Slika 4.11: Primer proceduralnega toka programa
V primeru, da želimo obrniti tok, lahko izdelamo aplikacijo z grafičnim uporabniškim
vmesnikom (Slika 4.12), kjer imamo obrazec z vsemi vidnimi vnosnimi polji, v katera v
poljubnem vrstnem redu vpisujemo podatke o študentu. Sedaj je aplikacija dogodkovno
usmerjena. Potem, ko vnesemo vse podatke študenta in pritisnemo gumb potrdi, se
program odzove na naša dejanja, namesto da program diktira, kaj mora početi uporabnik,
kot pri konzolni aplikaciji [7].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 30
Slika 4.12: Primer aplikacije z obrnjenim tokom
4.3.3 Nadzor nad ustvarjanjem-obračanje ustvarjanja odvisnosti
Običajno pri programiranju ustvarjamo nove objekte na sledeč način:
MojRazred objekt = new MojRazred().
Takšen način ustvarjanja novih objektov po navadi uporabljamo znotraj razredov, kateri
uporabljajo oziroma potrebujejo ustvarjen objekt. Če bi uporabili obračanje vmesnika, bi
najverjetneje uporabljali deklaracijo kot je ta:
IMojRazred mojaImplementacija = new MojRazred().
Nadzor nad ustvarjanjem objekta je še vedno v rokah razreda, ki objekt uporablja (objekt je
ustvarjen znotraj razreda, kateri objekt uporablja), čeprav je bil vmesnik obrnjen tako, da je
razred, ki novo ustvarjen objekt uporablja, še vedno odvisen od novega objekta. Lahko
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 31
rečemo, da je razred, ki novo ustvarjen objekt uporablja v vlogi visokonivojskega modula,
novo ustvarjen objekt pa v vlogi nizkonivojskega modula.
Torej lahko z gotovostjo trdimo, da običajen nadzor ustvarjanja pomeni, da je novo
ustvarjen objekt ustvarjen s strani razreda, ki novo ustvarjen objekt uporablja. Če želimo
nadzor ustvarjanja obrniti in izničiti odvisnost, moramo ustvarjanje novih objektov, ki jih
razred uporablja, prenesti izven razreda (tretji osebi) [8].
Mogoče bi se morali vprašati, zakaj si sploh želimo obrniti nadzor ustvarjanja?
Zato, ker želimo nove objekte oziroma nabor novih objektov ustvarjati na enem osrednjem
mestu. Načrtovalski vzorec, tovarniško metodo, lahko implementiramo zaradi istih
razlogov, kot želimo implementirati vzorec obračanje nadzora, ker vzorca v sebi nosita isto
idejo - ustvarjanje objektov na osrednjem mestu.
Osrednja ideja, namen tovarniške metode, se glasi nekako takole:
centralizacija ustvarjanja objekta določene vrste, kjer se izbere ena izmed več
možnih izvedb implementacij objekta.
Iz tega opisa lahko sklepamo, da se lahko odločimo za uporabo tovarniške metode ali
katere izmed drugih oblik obračanja nadzora vedno, ko imamo objekt ali vmesnik, kateri
ima več različnih možnih implementacij ter si poleg tega želimo logiko izbire postaviti na
osrednjo lokacijo [8].
Kdaj bi si torej želeli ustvarjanje objektov postaviti na osrednji lokaciji?
Za primer vzemimo klasičen primer uporabniškega vmesnika, ki omogoča uporabo
preoblek. Na voljo imamo različne razrede, kot so razredi za gumbe, vnosna polja, spustni
meniji ipd. Aplikacija omogoča poljubne implementacije preoblek zgoraj omenjenih
gradnikov našega uporabniškega vmesnika. Brez uporabe tovarniške metode bi morali
vedno, ko bi želeli na obrazcu prikazati kakšen gradnik, uporabiti podvajanje enega in
istega bloka programske kode v obliki switch stavka (Slika 4.13) [8].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 32
Slika 4.13: Podvajanje bloka programske kode
Potrebujemo torej posrednika, ki našemu uporabniškemu vmesniku posreduje gradnik, o
katerem mu ni treba vedeti podrobnosti (kakšne vrste je). In kot smo verjetno ugotovili,
vloga posrednika v našem primeru pripada tovarniški metodi, ki ima dostop do
uporabniških nastavitev in vse skupaj poenostavi v zgolj eno vrstico kode:
Button gumb = GumbTovarna.UstvariGumb();
Obračanje ustvarjanja odvisnosti lahko implementiramo na več različnih načinov.
Pomembnejši načini implementacije so [8]:
Tovarniška metoda
o Button gumb = GumbTovarna.UstvariGumb();
Iskalnik storitev
o Button gumb = IskalnikStoritev.Ustvari(IButton.class);
Injiciranje odvisnosti (npr. IOC zabojniki).
4.4 Injiciranje odvisnosti (Dependency Injection)
Injiciranje odvisnosti je tip obračanja odvisnosti, kjer premaknemo nastanek in vezavo
odvisnosti izven razreda. Je programski načrtovalski vzorec, ki nam omogoča razvoj šibko
sklopljenih (ohlapno vezanih) modulov programske opreme.
Injiciranje odvisnosti si lahko predstavljamo tudi na takšen način. Predstavljajmo si, da
smo v vlogi predšolskega otroka. V primeru, da smo lačni ali žejni in si želimo vzeti nekaj
iz hladilnika, lahko povzročimo težave. Lahko pozabimo zapreti hladilniška vrata, lahko
vzamemo nekaj kar nam starša ne pustita imeti. Lahko iščemo stvar, katere v hladilniku
nimamo ali pa ji je potekel rok uporabe. Kar bi morali narediti, je navesti potrebo, da pri
kosilu potrebujemo nekaj za piti in starša bosta vse potrebno uredila do takrat, ko se bomo
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 33
usedli za mizo. Z vidika objektno orientiranega razvoja programske opreme pomeni, da se
morajo sodelujoči razredi (predšolski otroci) zanašati na infrastrukturo (starše), za
zagotavljanje vseh potrebnih storitev [13].
Poglejmo si diagram injiciranja odvisnosti (Slika 4.14). Imamo nov razred, ki je v vlogi
injektorja, ki se zaveda obstoja razredov Razreda, IOdvisnosti ter Odvisnosti. Primarna
vloga injektorja je medsebojna vezava tipov. Poleg tega pa je Injektor odgovoren za
ustvarjanje objektov. Vrstni red operacij Injektorja poteka v naslednjem vrstnem redu [13]:
1. ustvarjanje objekta razreda Razred,
2. ustvarjanje objekta razreda Odvisnost in
3. prenos instance razreda Odvisnost v Razred.
Slika 4.14: Diagram injiciranja odvisnosti
4.4.1 Injiciranje preko konstruktorja
Je najbolj uporabljana oblika injiciranja odvisnosti. Poanta je v tem, da se odvisnost
prenese v odvisni razred preko konstruktorja (Slika 4.15).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 34
Slika 4.15: Injiciranje odvisnosti preko konstruktorja
4.4.2 Injiciranje preko lastnosti
Odvisni razred izpostavlja javno lastnost, preko katere so odvisnost injicira (Slika 4.16).
Slaba lastnost takšnega injiciranja je javna izpostavljenost odvisnosti, kar krši pravilo
enkapsulacije objektno orientiranega programiranja.
Slika 4.16: Injiciranje odvisnosti preko lastnosti
4.4.3 Injiciranje preko vmesnika
Redko uporabljano. Storitev ponuja vmesnik, katerega morajo implementirati odvisni
razredi. Vmesnik izpostavlja določene storitve (podpise metod), ki jih odvisen razred
implementira in uporabi (Slika 4.17).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 35
Slika 4.17: Injiciranje odvisnosti preko vmesnika
4.5 Pregled pojmov povezanih z obračanjem odvisnosti
Zaradi lažje predstave zgoraj opisanih pojmov smo izdelali sliko, s katero lažje razčlenimo
med sabo dokaj podobne pojme (Slika 4.18). Obračanje odvisnosti je načelo, možen način
razvijanja programske opreme. Glavno sporočilo načela zajema, da so visokonivojski
moduli neodvisni od nizkonivojskih modulov. Vendar nam načelo ne sporoča, kako
neodvisnost dejansko izvedemo. Obračanje nadzora je način implementacije obračanja
odvisnosti, vendar brez zagotovitve specifične implementacije. To so vidiki nadzora in
nadzor praktično povzroča odvisnost. Obračanje vmesnika in toka ter ustvarjanje
odvisnosti in vezava tipov (obračanje ustvarjanja odvisnosti) so načini, kako lahko
obrnemo nadzor in s tem tudi posledično obrnemo odvisnost. Injiciranje odvisnosti
zagotavlja praktično rešitev implementacije obračanja nadzora, ki se drži načela obračanja
odvisnosti [7].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 36
Slika 4.18: Pregled pojmov povezanih z obračanjem odvisnosti
Nevarnosti, ki jih je treba upoštevati pri injiciranju odvisnosti so [9]:
razkrivanje internih podrobnosti implementacije razreda:
o kršitev enkapsulacije,
o vbrizgavanje »drobovja« v razred;
preprečevanje odloženega nastanka odvisnosti:
o odvisnosti so ustvarjene preden jih potrebujemo,
o nevarnost velikih objektnih grafov (veriga odvisnosti, možna visoka poraba
pomnilnika pri inicializaciji);
ustvarjanje prevelikega števila odvisnosti (zlorabljanje).
4.6 IOC zabojniki
IOC zabojnik si lahko predstavljamo kot ogrodje za injiciranje odvisnosti. Njegova glavna
naloga je injiciranje odvisnosti. Lahko upravlja z življenjskim ciklom objektov.
Najpomembnejša funkcionalnost zabojnika je samodejno razreševanje konfiguriranih
tipov, torej dejansko izvajanje injiciranja odvisnosti namesto nas. Zabojnik se zaveda
obstoja odvisnosti (vmesnika ter realizacij kreditnih kartic) ter razreda, ki odvisnosti
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 37
uporablja (Kupec) (Slika 4.19). Ko razred Kupec potrebuje odvisnost (tipa
IKreditnaKartica), zabojnik ve katero instanco objekta (katero izmed kreditnih kartic) mora
v razred prenesti [9].
Slika 4.19: Razredni diagram IOC zabojnika
Razred Zabojnik (Slika 4.20) ima dve pomembni metodi:
metodo Registriraj in
metodo Razreši.
Metoda Registriraj registrira asociacijo podanih tipov in jo shrani v slovar. Dejanski primer
uporabe zgleda takole: Registriraj<IKreditnaKartica, Maestro>(). V tem primeru
Zabojnik zazna odvisnost tipa IKreditnaKartica in za implementacijo vmesnika izbere
konkretni objekt tipa Maestro.
Metoda Razreši razrešuje odvisnosti glede na podan tip. Delovanje metode lahko
razložimo v naslednjih korakih:
1. Metoda dobi v obliki parametra spremenljivko, katera predstavlja deklaracijo tipa.
2. Spremenljivka, katera predstavlja deklaracijo tipa, se primerja s shranjenimi
vrednostmi v slovarju. Če asociacija v slovarju ni najdena, je prožena izjema,
drugače je pridobljen razrešen tip.
3. Preko refleksije je dobljen javni konstruktor razrešenega tipa ter njegovi parametri.
4. Če je dobljen konstruktor brez parametrov, metoda ustvari in vrne ustvarjeno
instanco objekta razrešenega tipa, v nasprotnem primeru se parametri konstruktorja
s pomočjo rekurzije razrešijo ter shranijo v seznam. Nato se ustvari nova instanca
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 38
objekta razrešenega tipa, katera je ustvarjena s pomočjo konstruktorja s parametri,
kjer se dejansko uporabijo razrešeni parametri shranjeni v seznamu.
Slika 4.20: Izvedba razreda Zabojnik
Dejanski primer uporabe je viden na sliki spodaj (Slika 4.21). Preden postane razred
Zabojnik dejansko uporaben moramo registrirati dve asociaciji tipov. Kupca vezanega na
Kupca ter IKreditnaKartica, vezana na dejansko kreditno kartico MasterCard. Dodatne
implementacije vmesnika za Kupca nismo izvedli, ker obstaja samo ena vrsta kupca. Sedaj
nam preostane le to, da kličemo metodo zabojnika Razreši<Kupec>(). Zabojnik pregleda
zahtevane odvisnosti razreda Kupec. Ugotovi, da Kupec zahteva objekt, ki implementira
vmesnik IKreditnaKartica. Nato pregleda opredeljene povezave v slovarju ter vrne razred
MasterCard. Ta razred vstavi (injicira) preko parametra konstruktorja razreda Kupec in ga
nazadnje vrne kot instanco razreda Kupec, z vsemi razrešenimi odvisnostmi.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 39
Slika 4.21: Uporaba zabojnika v praksi
4.6.1 Castle Windsor
Castle Windsor je eden izmed prvih DI zabojnikov, ki so bili na voljo v ogrodju .NET. Je
del večjega odprtokodnega projekta, poznanega pod imenom Castle Project, ki ponuja
ponovno uporabne knjižnice za različne namene. Castle Windsor se lahko brez skrbi
uporablja povsem samostojno in ni v nikakršnem pogledu odvisen od ostalih komponent iz
projekta Castle [13].
Uporaba, registracija in razreševanje tipov
Uporaba zabojnika je sila enostavna. Zabojnik preprosto inicializiramo in pripravimo na
delo z uporabo izraza new WindsorContainer(). Pred dejanskim razreševanjem tipov
moramo komponente eksplicitno registrirati, to velja tudi za konkretne tipe (razred Kupec)
(Slika 4. 22). Sintaksa za registracijo tipov je tekoča (»fluent registration«) in jasno
razumljiva za uporabo. Registracija preslikave abstrakcije na konkreten tip je ravno tako
preprosta; stavku For<Abstrakcija>() na koncu sledi le še izraz
ImplementedBy<KonkretenTip>(). Pri registriranju več preslikav na isto abstrakcijo se ob
razrešitvi upošteva prvo registrirana preslikava. Nazadnje je potrebno nad zabojnikom le še
klicati metodo Resolve<Kupec>(), katera vrne instanco razreda Kupec z vsemi razrešenimi
notranjimi odvisnostmi, ki jih razrešen tip uporablja in potrebuje. V primeru uporabe
metode ResolveAll<Abstrakcija> zabojnik vrne niz dejanskih tipov vezanih na izbrano
abstrakcijo. Možna pa je tudi uporaba poimenovanja posameznih registracij preslikav na
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 40
abstrakcijo z edinstvenimi imeni, nad katerimi se v primeru razreševanja sklicujemo (
Slika 4.23) [13].
Slika 4. 22: Uporaba zabojnika Castle Windsor
Slika 4.23: Sklicevanje na edinstveno poimenovano registrirano preslikavo
V primeru, da imamo poseben razred, kateri kot konstruktor sprejeme dva dvoumna
parametra - instanci istega tipa, uporabimo poimenovanje registriranih preslikav
abstrakcije in dejanskih tipov (Slika 4.24). Z uporabo metode DependsOn je možna ročna
asociacija posameznih parametrov konstruktorja z dejanskimi poimenovanimi
registriranimi preslikavami (zlataMaestro in PlatinastaMasterCard).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 41
Slika 4.24: Eksplicitno navajanje poimenovanih odvisnosti in ročno navajanje uporabljenih
odvisnosti
Če želimo registracijo tipov organizirati v nekakšne ponovno uporabne zaključene enote -
pakete, lahko ustvarimo poljuben razred, ki implementira vmesnik IWindsorInstaller (Slika
4.25). V našem primeru se v razredu KupecInstaller pri metodi Install, podobno kot do
sedaj, definira nabor tipov za registracijo. Dejanska registracija našega paketa je izvedena
z izrazom zabojnik.Install(new KupecInstaller()).
Slika 4.25: Primer namestitvenega paketa
Življenjski cikel
Pri zabojniku Castle Windsor je mogoče uporabiti zajetno število različnih življenjskih
ciklov registriranih tipov objektov. Možno je celo ustvariti lastno definiran življenjski
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 42
cikel, vendar smo se pri diplomski nalogi osredotočili le na dva najpogostejša
konceptualna stila življenjske dobe objektov:
edinec (singleton) – ob vsaki razrešitvi se uporabi referenca najprej ustvarjene
instance objekta in
prehodni način (transient) – nova instanca objekta je ustvarjena ob vsaki razrešitvi.
Življenjski cikel registriranih tipov objektov pri Castle Windsor je privzeto v obliki edinca.
Življenjski cikel se lahko enostavno spreminja z uporabo izraza LifeStyle.TipCikla, ki se
pripne na koncu izraza za registriranje posameznega tipa (Slika 4.26). V primeru, da tip
življenjskega cikla ob registraciji ni naveden se privzeto uporabi življenjski stil edinca
[13].
Slika 4.26: Primer uporabe prehodnega življenjskega cikla
4.6.2 Unity
Unity Application Block ali krajše Unity je DI zabojnik ustvarjen izpod rok Microsoftove
skupine Patterns & practices. Opredeljen je kot sestavni del Microsoftove knjižnice
Enterprise Library, vendar popolnoma neodvisen od ostalih knjižnic. Je eden izmed
mlajših zabojnikov, vendar s presenetljivo velikim številom uporabnikov. Velikemu številu
uporabnikov zabojnika najverjetneje botruje neposredna povezava z Microsoftom ter zelo
obširna dokumentacija zabojnika. Zelo verjetno je Unity predstavil in populariziral koncept
DI zabojnikov povsem novemu segmentu neseznanjenih uporabnikov [13].
Uporaba, registracija in razreševanje tipov
Pri prejšnjem zabojniku (Castle Windsor) smo spoznali, da je pred razreševanjem
odvisnosti v zabojniku potrebno eksplicitno registrirati vse komponente. Zabojnik Unity
poseduje sposobnost samodejnega povezovanja komponent, dokler so uporabljeni
konkretni tipi z javnimi konstruktorji. Tako je za osnovno delovanje zabojnika potrebnih še
manj priprav [13].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 43
Za dejansko delovanje zabojnika je treba registrirati le preslikavo abstrakcije in dejanskega
tipa (v našem primeru vmesnik in dejanski razred, ki predstavlja kreditno kartico). Za
registracijo uporabimo metodo zabojnika s sledečim podpisom [10]:
RegisterType<Abstrakcija, DejanskiTip>([»Ime«]);
RegisterType<Abstrakcija, DejanskiTip>(new InjectionProperty(»Lastnost«,
vrednost)) v primeru injiciranja lastnosti.
Registrirane tipe je možno poimenovati in se nanje sklicevati z izbranim imenom tako kot
pri prejšnjem zabojniku. Pri registriranju več preslikav na isto abstrakcijo se ob razrešitvi
upošteva zadnja registrirana preslikava. Za razrešitev se uporablja metoda zabojnika
Resolve<Kupec>(), katera vrne instanco razreda Kupec z vsemi razrešenimi odvisnostmi
(Slika 4.27). V primeru, da je potrebna ročna sprememba razreševanja odvisnosti za
posamezen primer, se lahko pri razreševanju uporabi ročna razrešitev (Slika 4.28), vendar
je praktična uporaba takšnega načina dela nezaželena [10].
Slika 4.27: Uporaba zabojnika Unity
Slika 4.28: Ročno spreminjanje povezovanja tipov
Če želimo registracijo tipov organizirati v ponovno uporabne zaključene enote, je potrebno
definirati nov razred, ki deduje od abstraktnega razreda UnityContainerExtension (Slika
4.29). Potrebna je le še implementacija metode Initialize in definiranje izrazov za
registracijo tipov. Razširitev v zabojnik enostavno vključimo s pomočjo metode
AddExtension [10].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 44
Slika 4.29: Primer razširitve
V primeru, da imamo poseben razred, kateri kot konstruktor sprejeme dvoumna parametra-
instanci istega tipa, uporabimo poimenovanje registriranih preslikav abstrakcije in
dejanskih tipov (Slika 4.30). Z uporabo injicirnega konstruktorja in ročno definiranih
parametrov konstruktorja je možna ročna asociacija posameznih parametrov konstruktorja
z dejanskimi poimenovanimi registriranimi preslikavami (zlataMaestro in
platinastaMasterCard) [10].
Slika 4.30: Eksplicitno navajanje poimenovanih odvisnosti in ročno navajanje uporabljenih
odvisnosti v zabojniku Unity
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 45
Življenjski cikel
Zabojnik Unity privzeto po vsakem razreševanju odvisnosti ustvari novo instanco
razrešenega objekta. Življenjski cikel registriranih tipov objektov je privzeto v prehodnem
načinu. Življenjski cikel se lahko enostavno spreminja z uporabo upravljavca življenjskega
cikla dodatnega konstruktorjevega parametra pri registraciji tipov (Slika 4.31) [10].
Slika 4.31: Upravljanje življenjskega cikla registriranih tipov
4.6.3 Structure Map
Structure Map je prvi DI zabojnik, ki je bil na voljo v ogrodju .NET. Zabojnik je izdan pod
licenco Apache 2 OSS. Je zelo popularen in se kljub svoji starosti še vedno aktivno razvija
in poseduje mnoge moderne funkcije, ki so primerljive z ostalimi sodobnimi DI zabojniki.
Zato lahko brez skrbi njegovo »starost« interpretiramo kot dokaz zrelosti [13].
Uporaba, registracija in razreševanje tipov
Zabojnik Structure Map podobno kot Unity poseduje sposobnost samodejnega
povezovanja komponent, dokler so uporabljeni konkretni tipi z javnimi konstruktorji [13].
Za dejansko delovanje zabojnika je potrebno registrirati le preslikavo abstrakcije in
dejanskega tipa (vmesnik in dejanski razred, ki predstavlja kreditno kartico) (Slika 4.32).
Pri registraciji uporabimo metodo zabojnika z naslednjim podpisom, zapisano z uporabo
lambda sintakse [12]:
Configure(c => c.For<Abstrakcija>().Use<DejanskiTip>()).
Registrirane tipe je možno poimenovati in se nanje sklicevati z izbranim imenom tako kot
pri prejšnjem zabojniku. Pri registriranju več preslikav na isto abstrakcijo se ob razrešitvi
upošteva zadnja registrirana preslikava. Zaradi tekoče sintakse se pri registraciji izraz
prebere skoraj tako kot stavek ali kot navodila iz kuharskega recepta. Za razrešitev se
uporablja metoda zabojnika GetInstance<Kupec>(), katera vrne instanco razreda Kupec z
vsemi razrešenimi odvisnostmi [13].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 46
Slika 4.32: Delovanje zabojnika Structure Map
Če želimo registracijo tipov organizirati v ponovno uporabne zaključene enote je potrebno
definirati nov razred, ki deduje od abstraktnega razreda Registry (Slika 4.33). Potrebna je
le še definicija izrazov za registracijo tipov v konstruktorju izdelanega razreda. Razširitev
v zabojnik enostavno vključimo kar z inicializacijo novo izdelanega razreda kot parameter
konstruktorja zabojnika ali z uporabo lambda izraza v metodi Configure [13].
Slika 4.33: Primer razširitvenega razreda
V primeru, da imamo poseben razred, kateri kot konstruktor sprejeme dvoumna parametra
- instanci istega tipa, uporabimo poimenovanje registriranih preslikav abstrakcije in
dejanskih tipov (Slika 4.34). Z uporabo injicirnega konstruktorja in ročno definiranih
parametrov konstruktorja je možna ročna asociacija posameznih parametrov konstruktorja
(metoda Ctor), z dejanskimi poimenovanimi registriranimi preslikavami (zlataMaestro in
platinastaMasterCard) [13].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 47
Slika 4.34: Eksplicitno navajanje poimenovanih odvisnosti in ročno navajanje uporabljenih
odvisnosti v zabojniku Structure Map
Življenjski cikel
Zabojnik Structure Map privzeto po vsakem razreševanju odvisnosti ustvari novo instanco
razrešenega objekta. Življenjski cikel registriranih tipov objektov je privzeto v načinu na
zahtevo (per request) Ta življenjski cikel je pravzaprav mešanica med edincem in
prehodnim načinom. Vsak tip v razrešenem grafu objektov je mogoče gledati kot edinca
znotraj enega klica GetInstance. V primeru, da smo ponovno razrešili isti korenski tip, so
instance razrešenih tipov različne glede na ta dva neodvisno razrešena grafa objektov, ki
smo ju dobili pri dvokratnem razreševanju odvisnosti [14].
Življenjski cikel se lahko enostavno spreminja z uporabo dodatne metode LifeCycleIs in
parametra metode, ki predstavlja življenjski cikel pri registraciji tipov (Slika 4.35) [12].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 48
Slika 4.35: Upravljanje življenjskega cikla registriranih tipov pri Structure Map
4.6.4 Ninject
Zabojnik Ninject je eden izmed mlajših (začetek projekta v letu 2007) odprtokodnih
zabojnikov za ogrodje .NET. Starejše različice zabojnika so bile znane potem, da so bile
proti ostalim zabojnikom počasne, vendar je zadnja različica veliko hitrejša in se lahko
kadarkoli kosa z ostalimi zabojniki. Zabojnik postaja čedalje bolj popularen, najverjetneje
zaradi njegove razširljivosti in enostavnosti (enostaven programski vmesnik - API) pri
dejanski uporabi [11].
Uporaba, registracija in razreševanje tipov
Zabojnik Ninject poseduje podobno kot Unity in Structure Map sposobnost samodejnega
povezovanja komponent, dokler so uporabljeni konkretni tipi z javnimi konstruktorji.
Za dejansko delovanje zabojnika je potrebno registrirati le preslikavo abstrakcije in
dejanskega tipa (vmesnik in dejanski razred, ki predstavlja kreditno kartico) (Slika 4.36).
Pri registraciji se uporablja metoda zabojnika s sledečim podpisom [11]:
Bind<Abstrakcija>().To<DejanskiTip>().
Registrirane tipe je možno poimenovati in se nanje sklicevati z izbranim imenom tako kot
pri ostalih zabojnikih. Pri registriranju več preslikav na isto abstrakcijo se ob razrešitvi
upošteva zadnja registrirana preslikava. Zaradi tekoče sintakse pri registraciji se izraz
prebere skoraj tako kot stavek ali kot navodila iz kuharskega recepta. Pri razrešitvi se
uporablja metoda zabojnika Get<Kupec>(), katera vrne instanco razreda Kupec z vsemi
razrešenimi odvisnostmi [11].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 49
Slika 4.36: Uporaba zabojnika Ninject
Če želimo registracijo tipov organizirati v ponovno uporabne zaključene enote je potrebno
definirati nov razred, ki deduje od abstraktnega razreda NinjectModule (Slika 4.37).
Potrebna je le še implementacija metode Load in definiranje izrazov za registracijo tipov.
Modul se v zabojnik enostavno vključi kar kot parameter konstruktorja.
Slika 4.37: Primer Ninject modula
V primeru, da imamo poseben razred, kateri kot konstruktor sprejeme dvoumna parametra
- instanci istega tipa, uporabimo poimenovanje registriranih preslikav abstrakcije in
dejanskih tipov (Slika 4.34). Z uporabo poimenovanja instanc in izdelavo posebnega
razreda, v vlogi pomožnega atributa in ročno definiranih atributov pri parametrih
konstruktorja, je možna ročna asociacija posameznih parametrov konstruktorja z
dejanskimi poimenovanimi registriranimi preslikavami (zlataMaestro in
PlatinastaMasterCard). Razvijalci zabojnika so nam z idejo uvedbe posebnih atributov
resnično poenostavili delo in hkrati naredili programsko kodo veliko bolj berljivo in lažje
razumljivo. Hkrati je eksplicitno navajanje odvisnosti brez magičnih nizov veliko bolj
robustno in odporno v primeru sprememb (če napačno poimenujemo razred v vlogi
atributa se aplikacija niti ne prevede) [15].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 50
Slika 4.38: Eksplicitno navajanje poimenovanih instanc istega tipa s pomočjo imena in
posebnega razreda v vlogi atributa
Življenjski cikel
Zabojnik Ninject privzeto po vsakem razreševanju odvisnosti ustvari novo instanco
razrešenega objekta. Življenjski cikel registriranih tipov objektov je privzeto v prehodnem
načinu. Življenjski cikel se lahko enostavno spreminja z uporabo metode (npr.
InSingletonScope ali InTransientScope), ki se pripne na koncu izraza za registriranje
posameznega tipa (Slika 4.39). V primeru, da tip življenjskega cikla ob registraciji ni
naveden, se privzeto uporabi prehodni življenjski stil [11].
Slika 4.39: Upravljanje življenjskega cikla registriranih tipov pri Ninject.
4.6.5 Medsebojna primerjava zabojnikov
Vsi opisani zabojniki v diplomski nalogi so dobri, zanesljivi in primerni za vsakdanjo
uporabo. Castle Windsor je zelo zrel in izpopolnjen zabojnik primeren za največje
strokovnjake. Edine stvari, ki so lahko rahlo moteče, so registriranje čisto vsakega tipa, ki
se uporablja v zvezi z zabojnikom in rahlo čuden in prenasičen programski vmesnik. Pri
ostalih treh zabojnikih je zelo priročna sposobnost samodejnega povezovanja komponent,
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 51
dokler so uporabljeni konkretni tipi z javnimi konstruktorji, torej nepotrebnost registriranja
konkretnih tipov. Prav vsi imajo odličen programski vmesnik (API), ki je na daleč
razumljiv in enostaven za uporabo. Unity je zelo dobro dokumentiran. Edina vidna stvar,
ki manjka zabojniku Unity, je nevgrajena podpora za samodejno registracijo tipov. To
pomanjkljivost lahko izničimo z uporabo odprtokodnega projekta Unity Auto Registration.
Zelo inovativen programski vmesnik poseduje zabojnik Ninject, ki izredno poenostavi in
razjasni lastno delovanje. Izstopa tudi zaradi nekaterih posebnosti, kot je kontekstualna
vezava tipov, katera je zelo inovativno izvedena. Edina stvar, ki zabojnik rahlo pesti je
njegova hitrost, vendar ob pravilni uporabi zabojnika hitrost ne bi smela vplivati na
odzivnost in hitrost aplikacij, ki zabojnik uporabljajo. V tabeli 2 je prikazana medsebojna
primerjava zabojnikov.
Tabela 2: Medsebojna primerjava zabojnikov
Zabojnik Privzet
življenjski
cikel
Podprti načini
registracije
Tekoč
(fluent)
API
Posebnosti
Castle
Windsor
Edinec XML,
samodejna registracija,
konfiguracija s
programsko kodo
Da Vsestranski,
funkcionalno
izpopolnjen
Unity Prehodni XML,
konfiguracija s
programsko kodo
Da Dobra
dokumentacija,
skladen API
Structure
Map
Na zahtevo
(na
zahtevan
graf
objektov)
XML,
samodejna registracija,
konfiguracija s
programsko kodo
Da Aktiven razvoj,
vsestranskost
Ninject Prehodni XML,
samodejna registracija,
konfiguracija s
programsko kodo
Da Kontekstualna
vezava tipov,
enostavnost
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 52
5 TESTIRANJE APLIKACIJ
5.1 Testno usmerjen razvoj
Testno usmerjen razvoj (Test Driven Development - TDD) je postal eden izmed
najpomembnejših konceptov in dobrih praks pri sodobnem razvoju programske opreme.
TDD je bil zasnovan kot odgovor na težave in izzive, ki so nastajali tekom procesa
razvijanja programske opreme. Prakse TTD niso bile ustvarjene s strani podjetja ali
posameznika, ampak so bile ustvarjene s strani številnih razprav in argumentov o tem, kaj
je bilo narejeno v preteklosti, zakaj je spodletelo ter kaj bi lahko bilo spremenjeno in
storjeno bolje. Če si TTD predstavljamo kot zgradbo, so temelji zgradbe ustvarjeni iz
napak. Neuspeli projekti, katerih razvijalci so vedeli, da bi projekt lahko zgradili bolje, so
tisto na čem je zrasel TDD [4].
Načela, postopki in značilnosti testno usmerjenega razvoja programske opreme so [4]:
pomembnost medekipne komunikacije, spodbujanje pogostega komuniciranja med
razvijalci, poslovnimi uporabniki in preizkuševalci sistemov;
transparentnost projekta - uporaba javnih artefaktov (uporaba osrednjih desk z listi,
ki prikazujejo stanje projekta - Kanban table, grafi, tabele ipd.) za obveščanje
ekipe;
člani razvojne ekipe delijo breme odgovornosti enakopravno med sabo, ekipa nikoli
ne uspe ali zataji zaradi ene osebe, ampak uspe ali zataji kot ekipa;
posamezni razvijalci si ne lastijo dela izvorne kode, temveč je celotna izvorna koda
last razvojne ekipe, vsi člani ekipe so skupaj odgovorni za kakovost kode;
delo poteka v kratkih iterativnih razvojnih ciklih;
obvladovanje sprememb je temeljni del metodologije;
širše smernice sistema so določene vnaprej, podroben načrt je odložen do
dejanskega načrtovanega termina razvoja funkcionalnosti.
Agilne metodologije niso čudežna rešitev. Prav tako ne predstavljajo kaosa. Za ustrezno
uporabo zahtevajo večjo mero discipline. Poleg tega ne obstaja ena in edina pravilna agilna
metodologija, zato mora vsaka razvojna ekipa sama ugotoviti, katere vidike je potrebno
upoštevati, da je na koncu vidno kaj jim najbolj ustreza oziroma kaj je najbolje za njih [4].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 53
Ko se TDD uporablja v obliki metodologije načrtovanja aplikacij je najbolje, da je v
razvojni proces vključen poslovni uporabnik, ki pomaga razvijalcu pri definiranju logike
aplikacije. Včasih celo oblikuje nabor vhodnih in pričakovanih izhodnih podatkov. Takšen
način sodelovanja je bistven za razvijalčevo razumevanje poslovnih zahtev, ki se skrivajo v
določenih funkcionalnostih, katere razvija razvijalec. TDD zagotavlja, da je končni izdelek
v skladu s potrebami in zahtevami naročnika. Prav tako pomaga, da se upošteva obseg
funkcionalnosti in s tem pomaga razvijalcu razumeti, kdaj bo resnično konec z razvojem
glede na trenutno razvojno stanje funkcionalnosti [4].
5.2 TDD kot razvojna praksa
TDD kot razvojna praksa je varljivo preprost. Za razliko od običajnega razvoja, kjer
najprej ustvarimo določeno funkcionalnost (najsibo razred, okno, spletna stran ipd.), tukaj
najprej ustvarimo test. Ta razvojna praksa, ki je bolje poznana kot Test First Development
(TFD), se sprva zdi malce nerodna. S pisanjem testa v resnici ustvarjamo zahtevo, ki jo
načrtujemo v obliki programske kode. Med tem, ko sodelujemo s poslovnim uporabnikom,
ki pomaga opredeliti, kako bi naj izgledali testi, ustvarimo izvedljivo različico zahteve, ki
je sestavljena iz našega testa. Dokler ti testi padajo, naša programska koda ne izpolnjuje
poslovnih zahtev [4].
Pri TFD je razvoj aplikacije sestavljen iz treh neprestano ponavljajočih se korakov (Slika
5.1):
ustvarjanje testa, ki pade,
pisanje ravno dovolj kode, da je test opravljen,
izboljšanje programske kode.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 54
Slika 5.1: Diagram poteka razvoja programske opreme s pomočjo TFD razvoja
Ko napišemo prvi test, se aplikacija ne prevede, ker naslavlja še neobstoječi razred in
njegove metode. Sledi definiranje razreda in metod, katere imamo namen testirati. Na tej
točki test še vedno pade. Nato definiramo ravno zadostno količino kode, da test uspe. Ta
koda bi morala biti čim bolj preprosto napisana (kot smo jo seveda po naših močeh zmožni
ustvariti). Cilj postopka ni v tem, da pišemo kodo na podlagi potencialnih bodočih zahtev,
temveč upoštevamo samo trenutno zahtevo. Potencialne bodoče zahteve ne prilagajamo
dokler se zahteva ne spremeni oziroma dokler ni dodan nov test, ki razkrije pomanjkanje
funkcionalnosti. To nam posledično preprečuje pisanje pretirano zapletene programske
kode v primerih, kjer za zahtevano funkcionalnost zadošča že preprost algoritem. Cilj
katerega želimo doseči je ustvarjanje enostavno razumljive in lahko vzdrževane
programske kode [4].
Takoj, ko uspešno opravimo prvi test začnemo dodajati še več testov. Priporočljivo je imeti
zadostno število testov, torej v takšni meri, da so vse zahteve testirane funkcionalnosti
pokrite in izpolnjene. Poleg vsega moramo pri testiranju metod zagotoviti različne
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 55
kombinacije vhodnih podatkov. To vključuje vrednosti izven odobrenega območja. Takšne
tipe testov imenujemo negativni testi. Ti testi lahko torej testirajo različne vrednosti, ki ob
normalnem delovanju nebi smele priti na plano, pa vse do argumentov z null in praznimi
vrednostmi (npr. prazen niz) [4].
Prednosti TDD lahko povzamemo v naslednjih nekaj stavkih [4]:
TDD zagotavlja kakovostno kodo že od samega začetka. Razvijalce spodbuja, da
napišejo ravno dovolj kode, da opravijo test in s tem tudi izpolnijo zahtevo.
Logično je, da ima metoda z manj kode manjše možnosti za napake;
zagotavlja visoko stopnjo povezanosti med programsko kodo in poslovnimi
zahtevami. Če so naše zahteve ustrezno opisane v obliki testov in so vsi testi
uspešni, lahko z visoko stopnjo zaupanja trdimo, da je koda v skladu s poslovnimi
potrebami;
spodbuja komunikacijo s poslovnim svetom. Pri ustvarjanju testov se spodbuja
interakcija s poslovnimi uporabniki, kar omogoča pravilno zasnovo testov in lažje
razumevanje grajenega produkta;
pomaga ohranjati neuporabljeno kodo izven sistema. Mnogo razvijalcev je v svoji
karieri izdelalo kar nekaj aplikacij, pri katerih so zasnovali vmesnike in metode na
podlagi funkcionalnosti, katere bi v neki točki teoretično lahko vključili v
aplikacijo. To vodi do sistemov z obsežnimi deli kode in funkcionalnostmi, ki v
praksi niso nikoli uporabljane. Takšen način izdelave je drag. Pisanje dodatne kode
zahteva dodaten trud ter tudi trud za njeno vzdrževanje. Aplikacijo nepotrebni
dodatki naredijo veliko bolj neurejeno in nas odvračajo od delujoče kode, ki je v
resnici najpomembnejša;
zagotavlja vgrajeno regresijsko testiranje. Na voljo imamo serije testov, ki
zagotavljajo, da morebitne spremembe programske kode ne poškodujejo obstoječih
funkcionalnosti ali celo dodatno ustvarijo nove napake;
preprečuje ponavljanje ponavljajočih se napak. Takoj, ko pride poročilo o napaki je
ustvarjen nov test, ki najdeno napako izpostavi. Ko s pomočjo testa napako
odpravimo in ob naknadnih spremembah kode test ostaja nespremenjen, vemo da je
napaka odpravljena za vedno;
aplikacije zgrajene s TDD tehniko so odprte, razširljive in prilagodljive. Injiciranje
odvisnosti je ključni del TDD in arhitekture šibko sklopljenih sistemov. Takšen
sistem je robusten, enostaven za spremembe in odporen proti napakam.
5.3 Testi enot
Testi enot so temelji testno usmerjenega razvoja. Ko so testi enot pravilno usklajeni in
pravilno odražajo poslovne zahteve, postanejo kot neke vrste živa dokumentacija sistema,
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 56
takšna dokumentacija, ki lahko potrdi veljavnost napisane kode s pritiskom gumba. Testov
enot ni težko pisati. Predstavljajo tudi nekaj novih konceptov, kot so mock objekti, ki
omogočajo našim testom osredotočanje samo na kodo, ki se testira [4].
V najpreprostejšem smislu je test enote test, s katerim preverimo posamezno delovno
enoto. Delovna enota pomeni eno zahtevo za eno metodo, najmanjša enota aplikacije, ki je
primerna za testiranje. Prednost takšnega testiranja je dejstvo, da je test omejen le na
specifično enoto dela. Podrobnosti implementacije ostalih delov sistema so nepomembne
(razen v primeru neposrednih odvisnosti). To naredi pisanje testov in izhajajoče kode lažje.
Če se pojavi v naši kodi napaka, zaradi katere test pade, smo lahko razmeroma prepričani,
da je napaka izolirana v specifični delovni enoti in nam ni potrebno iskati igle v kopici
sena [4].
Skupne značilnosti testov enot so [4]:
izolirani od ostale kode,
usmerjeni,
ponovljivi,
predvidljivi,
hitri,
preprosti za implementacijo in
avtomatizirani.
Paziti moramo, da test ne prečka meje razreda, procesa, ker s tem postane integracijski test.
Postane težji za vzdrževanje in odpravljanje napak. Testi enot v aplikaciji dokazujejo le
prisotnost in ne odsotnost napak.
5.3.1 Mocking (oponašalni) objekti
Dobro izdelana programska oprema poskuša omejiti odvisnosti. Vendar pridemo do točke,
kjer morejo biti posamezne komponente sklopljene (povezane) z drugimi komponentami,
da skupaj tvorijo večjo celoto. Ta povezanost znotraj naše aplikacije ustvari mrežo
odvisnosti, ki se po navadi konča pri kakšnem zunanjem viru, kot je npr. podatkovna baza,
spletna storitev ipd. Mock objekti so simulirani objekti, ki oponašajo delovanje dejanskih
objektov na nadzorovan način. Mock objekt si lahko predstavljamo kot preizkusno lutko,
ki se uporablja pri testiranju trkov z osebnimi avtomobili [4] [21].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 57
Ko pišemo test enote za določeno metodo imamo namen testirati samo kodo, ki je
vsebovana znotraj izbrane metode. Poskušamo izolirati kodo, ki jo preizkušamo in oceniti
njeno veljavnost pod določenim pogojem. Pogoji se lahko opredelijo, ne samo v obliki
vhodnih podatkov testirane metode, ampak tudi iz konteksta in okolja v katerem se bo
koda izvrševala. Z izolacijo te kode lahko zagotovimo, da vsakič, ko test enote pade, to
kaže neposredno na napako znotraj testirane metode in ne na zunanje dejavnike,
komponente od katerih je metoda odvisna. Mock objekti lahko dejansko pohitrijo teste
enot. Predstavljajmo si, da bi ob testiranju določene metode vsakič brskali po podatkovni
bazi. Tako početje bi bilo počasno in nezanesljivo. Mock objekt, ki oponaša podatkovno
bazo, lahko vsakič nemudoma vrne vnaprej določene vrednosti, za vnaprej določene
parametre, brez nepotrebnega povezovanja na podatkovno bazo in izvrševanja SQL
poizvedb. Ker so testi enot predvidljivi in dosledni, pričakujemo vedno, da bo vrednost, ki
jo metoda vrne, če metoda kot parametre sprejme argumente A, B in C, vedno vrnjena kot
D. Če v testih uporabljamo zunanje vire, ni zagotovljena konsistentnost vhodnih in
izhodnih podatkov. Z oponašanjem vira zagotovimo dosledne in zanesljive vhodne in
izhodne podatke za testiranje napisanih metod [4].
Veliko večjih projektov razvijajo ekipe z večjim številom razvijalcev. V teh primerih testi
enot ne smejo vplivati na rezultate testiranj sodelavcev. Obstaja velika verjetnost, da med
zbirko testov obstajajo takšni testi, ki spreminjajo stanje podatkov v podatkovni bazi in še
nekateri testi, ki se zanašajo na podatke v določeni tabeli podatkovne baze. Če pride do te
situacije, obstaja obenem velika verjetnost, da več razvijalcev požene teste istočasno.
Zaradi tega bodo vse razvijalce, ki so istočasno pognali določene teste, pričakali neuspešno
opravljeni testi, zaradi konflikta pri dostopu do podatkov. Kot smo že prej ugotovili za ta
problem obstaja idealna rešitev ponovno v obliki mock objekta [4].
Mock objekti so nekoliko splošen izraz, ki zajema družino nadomestkov, ki se uporabljajo
pri testiranju enot. Obstajajo naslednje vrste mock objektov [4]:
dummy objekti – so enostavni oponašalni objekti, ki po navadi vrnejo vnaprej
določen odgovor (vrednost), odgovora niso zmožni spreminjati glede na različne
vhodne parametre;
fakes, stubs objekti – so podobni kot dummy objekti, vendar so sposobni
spreminjati odgovore (vrednosti) glede na vhodne parametre;
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 58
mock objekti – zagotavljajo iste funkcionalnosti kot stubs objekti, vendar so bolj
kompleksni in so sposobni spremljati vrstni red zaporedja in števila klicev
določenih metod ter glede na te podatke ustrezno reagirati – z njimi opredelimo in
preverimo pričakovanja.
5.3.2 Moq
Moq hitro postaja eden izmed najbolj priljubljenih mock ogrodij za .NET. Ima soliden
nabor funkcij, je enostaven za uporabo in ima dobro podporo skupnosti, ki zagotavlja
nenehen razvoj in izboljšave funkcionalnosti ogrodja. Moq je odprtokodno ogrodje, ki nam
daje možnosti za hitro ustvarjanje stub in mock objektov. Na voljo imamo tudi posebni
domenski jezik (Domain Specific Language) za določanje izvršilnih pravil za mock vire.
Ogrodje je bilo zgrajeno tako, da izkorišča nove naprednejše funkcionalnosti .NET 3.5 in
C# 3.0, natančneje lambda izraze. Njegovo glavno vodilo je, da je lahek in enostaven za
uporabo [4].
5.3.2.1 Osnove Moq
Predstavljajmo si, da imamo preprosto aplikacijo, katera vsebuje vmesnik z metodo Izvedi
in razred, ki vmesnik implementira. Namen metode Izvedi je simuliranje dolgo trajajočega
procesa, kot je na primer poizvedba po podatkovni bazi (Slika 5.2) [4].
Slika 5.2: Primer razreda, ki simulira dolgo trajajočo operacijo
Ta primer (Slika 5.3) prikazuje, kako lahko dolgo trajajoči procesi naredijo testiranje enot
izredno počasno. Test enote mora pred dejanskim preverjanjem čakati, da se proces izvede.
Test enote rabi celih pet sekund za dokončno izvedbo. Predstavljajmo si, da imamo še
ducate podobnih testov, ki trajajo tako dolgo kot ta test enote. Če bi testi trajali tako dolgo,
bi bilo testiranje zelo dolgotrajno in nepraktično.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 59
Slika 5.3: Testiranje dolgo trajajoče metode
Da testiranje enot ostane hitro in praktično za uporabo, smo uporabili mock objekt.
Ustvarili smo novo privatno spremenljivko _knjiznicaMock, katera predstavlja Mock
objekt. Mock objekt smo ustrezno nastavili s Setup in Returns metodama. V našem
primeru, če smo nad Mock objektom klicali metodo Izvedi, z vrednostjo argumenta 5, je
metoda vrnila niz »Mock vrednost« (Slika 5.4).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 60
Slika 5.4: Primer testa z uporabo Moq orgodja
Po navadi pri Mock objektih uporabljamo statične vrednosti, ker hočemo pri testih enot
imeti pričakovane vhodne in izhodne podatke. V izjemnih primerih lahko uporabimo
konstrukt It.IsAny<PodatkovniTip>, kateri preverja samo podatkovni tip argumenta
metode tako, da je v našem primeru (Slika 5.5) metoda, za različne vrednosti vhodnega
parametra tipa int, vedno vrnila isto izhodno vrednost. Ogrodje poseduje zmožnost
dostopanja do vhodnih parametrov in njihovo uporabo v vrnitvenih stavkih [4].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 61
Slika 5.5: Primer testa z uporabo Moq ogrodja in uporabe posebnega konstrukta IsAny
V primeru, da želimo preveriti, če metoda v določenih pogojih vrže izjemo (Slika 5.6)
lahko to prav tako preprosto izvedemo s kombinacijo metod Setup in Throws. V našem
primeru so bile napačne vse negativne celoštevilske vrednosti vključno z nič. V tem
intervalu je Mock objekt preprosto prožil ArgumentException izjemo.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 62
Slika 5.6: Konfiguriranje Moq ogrodja, da pri določenih pogojih proži izjemo
Nekateri razvijalci pri testiranju uporabljajo vzorec Arrange Act Assert – AAA (razporedi,
ukrepaj in preveri). Ta vzorec ni pravilo, brez katerega testi enot niso mogoči, ampak le
smernica, ki naredi teste bolj strukturirane, jasne in lažje razumljive. V našem primeru
(Slika 5.7) smo najprej razporedili vse potrebne vire, mock objekte in ostale stvari, ki so
bile predpogoj za uspešno izvajanje testa. Nato smo izvedli določen test in na koncu
preverili, če je bilo delovanje testirane funkcionalnosti takšno, kot je bilo predvideno.
Slika 5.7: Arrange Act Assert vzorec
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 63
5.4 Testiranje JavaScripta
V zadnjih letih so JavaScript ogrodja, kot je jQuery zelo omilila bolečino, katero je
spletnim razvijalcem povzročil DOM. Ta ogrodja razvijalcem poenostavijo delo z DOM
modelom in poenostavijo kompleksnost JavaScript testiranja.
Ene izmed najbolj pogostih napak katere počnejo spletni razvijalci so to, da JavaScript
kodo ne abstrahirajo v ločene datoteke. Veliko razvijalcev vse skupaj združuje v eno
veliko skripto ali celo podvajaja eno in isto kodo preko različnih spletnih strani. Kar ne
spada pod dobro prakso [4].
5.4.1 qUnit testirno ogrodje
qUnit je testirno ogrodje za JavaScript. Omogoča testiranje kode na podoben način kot
ostala .NET testirna ogrodja kot so xUnit, NUnit ipd., vendar z razliko v tem, da je qUnit
namenjen izključno testiranju JavaScripta. Ogrodje za testiranje uradno uporablja razvojna
ekipa jQuery-ja. V naslednjih nekaj primerih smo poskušali predstaviti osnovne napotke s
katerimi lahko začnemo testirati z uporabo qUnit ogrodja [4].
JavaScript kodo, ki jo imamo namen testirati, pišemo v ločene datoteke. Teste smo
ustvarili v poddirektoriju z imenom UnitTests (Slika 5.8). Predpogoji za delovanje naših
testov sta bili datoteki qunit.js in qunit.css ter ogrodje jquery. Testi so napisani v
JavaScript kodi. Mesto izvrševanja testov je vsebovano v HTML datoteki. Konvencija
poimenovanja HTML testirnih datotek je v obliki »imeJSDatoteke + Tests.html« npr.
TransakcijskiRacunTests.html, kjer so potekali vsi testi v povezavi z objekti
TransakcijskiRacun.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 64
Slika 5.8: Struktura qUnit projekta
Primer testiranja prikazuje transakcijski račun (Slika 5.9). Vsebuje podatke o številki
računa, trenutnem stanju na računu in limitu. Možen je prenos denarnih sredstev iz enega
na drug račun in dvigovanje gotovine iz bankomata.
Slika 5.9: Preprosta logika transakcijskega računa napisana v JavaScript-u
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 65
Za ustrezno delovanje testov je bilo potrebno ustvariti šablono HTML datoteke (Slika
5.10), ki je naložila vse potrebne datoteke, pognala teste in prikazala rezultate testov enot.
Sklicevati smo se morali na skripte qUnit, TransakcijskiRacun in CSS datoteko, ki je bila
odgovorna za pravilno oblikovanje testne šablone.
Slika 5.10: Okvir v katerem se izvajajo qUnit testi enot
Testirali smo osnovne funkcionalnosti transakcijskega računa (Slika 5.11):
pravilno ustvarjanje objekta, s pravilnimi podanimi vrednostmi;
testiranje prenosa denarnih sredstev iz enega na drug račun;
testiranje prekinitve transakcije med računoma zaradi prenizkega stanja na računu;
dvig previsokega zneska iz bankomata, ki se ne sme zgoditi zaradi prenizkega
stanja na računu.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 66
Slika 5.11: Izdelani qUnit testi enot
Teste (Slika 5.12) smo enostavno pognali z navigiranjem do lokacije HTML datoteke na
naslovu: http://localhost:3825/Scripts/UnitTests/TransakcijskiRacunTesti.html. Prikazali
so se nam rezultati testov na lep in pregleden način. Uspešno opravljeni testi so bili
obarvani z zeleno barvo, neuspešno opravljeni testi pa z rdečo barvo.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 67
Slika 5.12: Rezultati testov enot
Sedaj, ko smo videli, da zamišljene funkcionalnosti delujejo, kot je bilo predvideno, bi se
lahko v resničnem razvojnem projektu brez skrbi lotili dejanske implementacije objekta v
produkcijski kodi.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 68
6 PRIMER RAZVOJA SPLETNE APLIKACIJE V ASP.NET
MVC 4
Ker je spletna aplikacija zelo obsežna in kompleksna smo se odločili, da naredimo
preprosto moderno šibko sklopljeno aplikacijo, ki se drži načela obračanja nadzora. Ta
aplikacija lahko služi kot nekakšne vrste vodič do izgradnje modernih šibko sklopljenih
aplikacij. Po predstavitvi enostavnejše aplikacije smo predstavili nekatere ključne
značilnosti kompleksnejše spletne aplikacije Evropski plačilni nalog in nekatere specifične
podrobnosti, ki smo jih uvedli tekom izgradnje spletnega portala.
6.1 Vodič do razvoja enostavne spletne aplikacije
Naša preprosta aplikacija je imela glavno nalogo, da prikaže seznam izdelkov na pozdravni
strani spletne aplikacije. Podatkovna baza (Slika 6.1) je sestavljena iz štirih entitet:
uporabniki, vloge, uporabniki_vloge in izdelki.
Slika 6.1: Podatkovna baza spletne aplikacije
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 69
Spletna aplikacija je omogočala registracijo in prijavo. Vsak uporabnik je imel določeno
uporabniško vlogo. Stran je kupcem na naslovni strani, ki so imeli status zvestega kupca,
prikazala izdelke z uveljavljenim 10 % popustom napram navadnim uporabnikom. Projekt
je uporabljal tri-nivojsko arhitekturo. Aplikacija (Slika 6.2) je bila logično strukturirana na
naslednje podprojekte:
SpletnaTrgovinaDAL, ki je vsebovala logiko do dostopa do podatkov, kot so
razne CRUD (Create, Update, Delete) operacije nad podatkovno bazo;
SpletnaTrgovinaDLL, ki je vsebovala domensko oziroma poslovno logiko;
SpletnaTrgovinaWebMvc, spletna ASP.NET MVC 4 aplikacija, ki je služila kot
uporabniški vmesnik.
Slika 6.2: Organizacija projektov v spletni aplikaciji
Aplikacija je uporabljala injiciranje odvisnosti, zato je bilo potrebno s pomočjo dodatka
NuGet prenesti in namestiti Ninject.MVC knjižnico, ki je omogočala integracijo DI
zabojnika Ninject z ASP.NET MVC 4. Ker je bila aplikacija šibko sklopljena, je bilo
možno enostavno zamenjati določene module z drugimi. V našem primeru smo uporabljali,
v nivoju dostopa do podatkov, Entity Framework, ki je bil vezan z Microsoft SQL Server
2008 podatkovno bazo in MVC 4 spletno aplikacijo, na nivoju uporabniškega vmesnika.
Zaradi šibko sklopljene arhitekture se lahko v prihodnosti enostavno odločimo in
zamenjamo implementacijo podatkovnega nivoja z drugim ogrodjem, kot je NHibernate.
Zamenjamo lahko tudi podatkovno bazo in uporabimo MySql, PostgreSql ipd. Prav tako
lahko zamenjamo in spremenimo nivo uporabniškega vmesnika z ASP.NET Web Forms
ali celo kakšnim uporabniškim vmesnikom, ki ne temelji na spletni uporabi, kot sta
Windows Forms ali WPF aplikacija. Vse to je možno zaradi sestave naše aplikacije.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 70
V uporabniškem vmesniku - MVC4 aplikaciji smo dodali nov krmilnik in ustvarili novo
akcijo. Akciji smo dodali strogo tipiziran pogled (Slika 6.3), ki je predstavljal zbirko
znižanih izdelkov in osnovno obliko pogleda. Nato smo v krmilniku uredili akcijo, kjer
smo ustvarili zbirko znižanih izdelkov in jih prenesli v model.
Slika 6.3: Izgled pogleda
Takrat se je aplikacija pri zagonu izvedla brez napak, vendar je bil prikazan prazen seznam
izdelkov. Naloga zagotavljanja znižanih izdelkov je bila pod okriljem domenskega modela.
Domenska logika je bila navadna C# knjižnica, ki je bila vključena v projekt. Vsebovala je
POCO objekte in abstraktne tipe. POCO objekti so predstavljali domeno, abstraktni tipi, ki
so bili udejanjeni v obliki abstraktnih razredov (lahko bi tudi uporabili programski
konstrukt vmesnik) pa so zagotavljali obliko abstrakcije, ki je služila kot glavna zunanja
vstopna točka do domenskega modela. Načelo načrtovanja vmesnikov namesto konkretnih
razredov je bil temelj DI tehnike, ki je omogočala medsebojno zamenjavo konkretnih
implementacij [13].
Potem smo morali dodati referenco iz nivoja uporabniškega vmesnika na domenski nivo.
Kot smo že omenili, smo morali na tem nivoju ustvariti repozitorij izdelkov (Slika 6.4),
kateri je zagotovil abstrakcijo nad dostopom do podatkov. Pravi repozitorij bi imel kopico
dodatnih funkcionalnosti, vendar smo se držali načela izdelave, ki se imenuje izdelava od
zunanjosti proti notranjosti, kjer smo začeli izdelovati stvari na nivoju uporabniškega
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 71
vmesnika in smo se nato počasi premikali do globljih plasti. Poleg tega smo, glede na
zahteve dane naloge, sproti ustvarjali razrede in metode, ker je bilo k aplikaciji lažje
dodajati nove, kot pa brisati stare funkcionalnosti, ki se na koncu niti niso uporabljale.
Primer kompleksnejšega repozitorija (repozitorija uporabnikov in uporabniških vlog) si
lahko pogledamo v izdelani aplikaciji, ki je kot priloga dodana poleg diplomske naloge
[13].
Slika 6.4: Ustvarjanje repozitorija izdelkov na domenskem nivoju
Za vse repozitorije smo implementirali storitve (npr. IzdelekStoritev), preko katerih smo
vršili poslovno logiko (Slika 6.5). Repozitorij izdelkov smo s pomočjo DI zabojnika
Ninject injicirali preko konstruktorja. Izdelek storitev pa je ob klicu metode preko
repozitorija vračal izdelke.
Slika 6.5: Logika pridobivanja izdelkov na domenskem nivoju
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 72
Naknadno smo morali spremeniti krmilnik spletne aplikacije (Slika 6.6). Dodali smo novi
konstruktor, ki je sprejel repozitorij izdelkov. Nadzor nad zagotavljanjem repozitorija
izdelkov h krmilniku je bil prepuščen DI zabojniku.
Slika 6.6: Spremenjen krmilnik prilagojen injiciranju odvisnosti preko konstruktorja
Sledila je implementacija izdelek storitve (Slika 6.7), kjer smo dejansko pridobivali
izdelke, katere smo dodatno znižali v primeru uporabnikov s statusom zvestih kupcev. V
tej točki repozitorij izdelkov še ni bil injiciran v krmilnik s pomočjo DI zabojnika.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 73
Slika 6.7: Implementacija izdelek storitve
Na tej točki je bila aplikacija nefunkcionalna zaradi sledečih stvari [13]:
ni bilo dejanske izvedbe repozitorija izdelkov, potrebna je bila še implementacija
konkretnega repozitorija izdelkov, ki pridobiva izdelke neposredno iz podatkovne
baze;
ASP.NET MVC privzeto pričakuje, da imajo krmilniki privzete konstruktorje, ki so
brez parametrov. Na vrsto je stopil Ninject, ki je bil v vlogi ustvarjalca krmilnikov
(tovarne) z dodatnimi parametri, vendar trenutno še ni bil pravilno konfiguriran.
V domenskem modelu smo delali samo s tipi, definiranimi znotraj domenskega modela.
Koncepti (npr. Izdelek) domenskega modela so bili definirani kot POCO objekti.
Domenski model je moral imeti zmožnost komuniciranja z zunanjim okoljem, v našem
primeru s podatkovno bazo. Ta potreba je bila oblikovana v obliki abstraktnih razredov
(npr. repozitorijev), ki smo jih na končni točki nadomestili z dejanskimi implementacijami,
katere smo predstavili v naslednjih nekaj vrsticah [13].
Za dostopanje do podatkov v podatkovni bazi smo uporabili ogrodje Entity Framework. S
pomočjo čarovnika, vgrajenega v Visual Studiu, smo enostavno ustvarili entitetni model.
Entitetni model, implementiran z ogrodjem Entity Framework, je bil od te točke naprej
samo implementacijska podrobnost nivoja dostopa do podatkov, vendar smo lahko z
njegovo pomočjo implementirali konkretni repozitorij izdelkov (Slika 6.8) [13].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 74
Slika 6.8: Konkretni repozitorij izdelkov implementiran na nivoju dostopa do podatkov
Domenski model in nivo dostopa do podatkov sta hkrati določala razred z imenom Izdelek.
Izmed teh razredov je bil pomemben razred, ki je enkapsuliral domenski koncept Izdelka,
torej tisti, ki je bil definiran v domenskem modelu. Razred, definiran na nivoju dostopa do
podatkov, je bil samo artefakt oziroma implementacijska podrobnost ogrodja Entity
framework [13].
Zadnja stvar, katera nas je ločila do delujoče aplikacije, je bila konfiguracija odvisnosti v
zabojniku Ninject. V razred NinjectWebCommon smo morali dodati le nekaj vrstic kode,
katera je povezovala preslikavo abstraktnih tipov repozitorijev v dejanske implementacije
repozitorijev (Slika 6.9).
Slika 6.9: Asociiranje preslikav v zabojniku
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 75
Sedaj se je aplikacija enostavno prevedla in uspešno izvedla. V primeru, da se je na portal
prijavil navaden kupec, so ostale cene izdelkov normalne (Slika 6.10). Če se je v portal
prijavil kupec s statusom zvestega kupca, so se cene izdelkov še dodatno znižale, za 10
odstotkov (Slika 6.11).
Slika 6.10: Izgled strani, ko je vanjo prijavljen navaden uporabnik
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 76
Slika 6.11: Uveljavljen 10% popust zaradi uporabnika s statusom zvestega kupca
Zaradi boljšega razumevanja si poglejmo vrstni red interakcij pri pridobivanju znižanih
izdelkov (Slika 6.12).
Pri zagonu aplikacije se je ustvarila nova prilagojena tovarna krmilnikov implementirana s
pomočjo Ninject MVC knjižnice. Ko je do aplikacije prišel zahtevek za dostop do strani, je
zabojnik ustvaril novo instanco krmilnika, v katerega je, z uporabo injiciranja preko
konstruktorja, vstavil novo instanco repozitorija izdelkov. Aplikacija je na instanci
kontrolnika klicala akcijo Index, ki je ustvaril novo instanco storitve izdelkov, katera je
sprejela instanco repozitorija, v obliki parametra konstruktorja. Storitev izdelkov je izvedla
metodo, ki je pridobila znižane izdelke preko repozitorija izdelkov [13].
Repozitorij iz entitetnega modela, s pomočjo ogrodja Entity Framework, je pridobil
seznam izdelkov, kateri so se v obliki modela pogleda prenesli v ViewResult in izrisali v
index pogledu.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 77
Slika 6.12: Diagram poteka, ki prikazuje potek interakcij v aplikaciji pri dostopanju do
index pogleda in posledičnem prikazu znižanih izdelkov
Na koncu si poglejmo arhitekturno sestavo in graf medsebojnih odvisnosti posameznih
projektov (Slika 6.13). Pomembna stvar končne arhitekture je bila v tem, da je bil
domenski model popolnoma neodvisen od vseh ostalih nivojev in se je zato lahko
uporabljal kot samostojni modul. Poleg tega pa smo lahko, kot smo že omenili zgoraj, po
mili volji nadomestili nivoja uporabniški vmesnik in dostop do podatkov z drugimi
implementacijami. To je ta pravi čar arhitekture šibko sklopljenih aplikacij!
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 78
Slika 6.13: Struktura in prikaz medsebojnih odvisnosti v aplikaciji
Dodatna stvar, ki je vredna omembe, je bila uporaba lambda izrazov. Lambda izrazi so
lahko zelo uporabni (Slika 6.14). Brez uporabe lambda izrazov bi, pri iskanju in
pridobivanju uporabnikov, morali narediti kopico metod, če bi želeli filtrirati uporabnike
glede na določene karakteristike. Z uporabo lambda izraza smo lahko število metod skrčili
na eno samo metodo, ki je imela kot parameter definiran delegat (Slika 6.15). Na mestu
anonimnega delegata smo definirali anonimno funkcijo (Slika 6.14), ki je kot vhodni
parameter sprejela uporabniški objekt in vrnila boolean vrednost, kar je bila idealna stvar
za filtriranje rezultatov.
Slika 6.14: Primer lambda izraza
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 79
Slika 6.15: Implementacija metode, ki pridobi uporabnika glede na določen kriterij
Do problema je prišlo, ko smo želeli isti izraz uporabiti stopnjo nižje v nivoju dostopa do
podatkov. Takrat smo morali pretvoriti vhodni parameter izraza, da je sprejel entitetni
uporabniški razred namesto uporabniškega razreda iz domenske logike. Ta problem smo
odpravili s pomočjo razreda, ki je pretvoril izraze v pravilno obliko (Slika 6.16). Sedaj smo
za filtriranje uporabnikov lahko enostavno uporabili spremenjen izraz, kateri je imel
spremenjen parameter in isto telo kot stari izraz (Slika 6.17) [19].
Slika 6.16: Razred, ki omogoča pretvorbo dreves izrazov
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 80
Slika 6.17: Pretvorba drevesa izrazov, da lahko deluje nad uporabnikom nivoja dostopa do
podatkov
Pri testiranju (Slika 6.18) smo eksperimentirali z NuGet paketom AutoFixture, ki je s
kombiniranjem ogrodja Moq omogočal enostavnejše testiranje z avtomatiziranjem
pripravljanja enostavnejših spremenljivk in objektov, ki po navadi prikazujejo nekakšno
začetno stanje testa, kar je naredilo ustvarjanje testov enot hitrejše in enostavnejše.
Slika 6.18: Primer testiranja s pomočjo AutoFixture
6.2 Spletni portal Evropski plačilni nalog
6.2.1 Predstavitev projekta
Spletni portal Evropski plačilni nalog omogoča enostavno oddajo plačilnih nalogov
oziroma sodnih zahtevkov preko spleta. Zasnovan je bil za meddržavno uporabo. Vendar
je ta prototip zaenkrat orientiran le na slovensko sodstvo.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 81
Postopek za oddajo evropskega plačilnega naloga je zelo preprost [16]:
1. Pravilno izpolnjen obrazec za evropski plačilni nalog.
2. Uspešno izpolnjen čarovnik, v katerega vpišemo podatke o višini terjatve, podatke
o tožniku in tožencu ter pravilno izpolnjen obrazec E v PDF formatu.
3. Potrditev oddaje podatkov o plačilnem nalogu in prenos digitalno podpisanega
potrdila, ki ga izda portal in potrjuje, da je uporabnik plačilni nalog resnično oddal.
Slika 6.19: Evropski plačilni nalog, obrazec E
V Sloveniji imamo:
11 okrožnih sodišč,
44 okrajnih sodišč.
Poslan plačilni nalog se dodeli določenemu sodišču glede na dve karakteristiki:
višina zneska zahtevka,
kraj prebivališča tožene stranke.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 82
Če je višina zahtevka višja od 8.345,85€ je plačilni nalog pod pristojnostjo okrožnega
sodišča, drugače pa je pod pristojnostjo okrajnega sodišča. Sodba se izvrši v tistem sodišču
katero je pristojno za kraj v katerem je stalno prebivališče toženca.
6.2.2 Podrobnosti izdelave projekta
6.2.2.1 Arhitekturne podrobnosti projekta
Portal temelji na sledečem konceptualnem modelu (Slika 6.20), ki vsebuje naslednje
pomembnejše entitete [16]:
• Uporabniki – shranjevanje podatkov o registriranih uporabnikih spletnega portala;
• Uporabniške vloge – definiranje vlog in dovoljenj uporabnikov kot so navaden
uporabnik, administrator, sodnik ipd.;
• Države – seznam držav v Evropski uniji;
• Občine – seznam občin, vsaka občina je vezana na določeno državo;
• Naselja – seznam naselij, ki so vezane na občino ter pošto;
• Pošte – seznam pošt;
• Sodišča – seznam sodišč;
• Tipi sodišč – možni tipi sodišč (okrožno ali okrajno sodišče);
• Plačilni nalogi – vsebuje plačilne naloge, ki jih oddajo uporabniki spletnega portala v
obliki PDF datotek ter podatke o tožencih in tožnikih, vsak plačilni nalog je vezan na
določenega sodnika v izbranem sodišču, kateremu je bil nalog dodeljen.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 83
Slika 6.20: Izdelan entitetni model portala
Ker projekt vsebuje veliko entitet, nad katerimi se vršijo relativno podobne CRUD
operacije (operacije ustvarjanja, posodabljanja in brisanja podatkov v entiteti), smo se
odločili uporabiti generični repozitorij, ki vsebuje množico skupnih metod za manipulacijo
nad entitetami [16]:
Delete – brisanje posameznega vnosa ali skupine vnosov posamezne entitete
glede na podane filtre, karakteristike;
Update – posodabljanje, spreminjanje posameznega vnosa izbrane entitete;
Insert – dodajanje novega vnosa v posamezno entiteto;
Get, GetById – pridobivanje posameznega vnosa ali skupine vnosov posamezne
entitete glede na podane filtre, karakteristike.
To je bil bistven del naloge, ki se je razlikoval, od v vodiču zgoraj, predstavljenega
repozitorija. Takšen način ustvarjanja generičnega repozitorija smo iz vodiča izpustili, ker
bi vse skupaj samo nepotrebno dodatno zakompliciralo težavnost izdelave aplikacije,
katere namen je bil ravno splošna preprostost.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 84
Pri ustvarjanju specifičnih repozitorijev (Slika 6.21), kot je na primer repozitorij naselij ali
repozitorij sodišč, smo vedno dedovali iz generičnega repozitorija tako, da je vsak na novo
izpeljan repozitorij že vseboval delujoče skupne metode za manipulacijo nad podatki
entitet. V izpeljanih repozitorijih smo naknadno dodali samo tiste metode, ki so bile
potrebne za specifične operacije nad posameznimi entitetami [16].
Izbran vzorec je omogočal plast abstrakcije (skril je podrobnosti implementacije dostopa
do podatkov) med poslovno logiko in dostopom do podatkov tako, da je promoviral šibko
sklopljenost posameznih plasti, zmanjšanje podvajanja kode, boljšo strukturo, preglednost
in vzdrževalnost kode ter boljšo podporo za testiranje enot.
Slika 6.21: Razredni diagram repozitorijev
6.2.2.2 Vzorec delovna enota (Unit Of Work)
Obstoječe repozitorije smo združili v načrtovalski vzorec Unit of work (delovna enota)
(Slika 6.22), ki je omogočal uporabo skupnega objektnega konteksta različnim
repozitorijem, ki so bili del iste transakcije. Povedano z drugimi besedami: s pomočjo
vzorca je bilo možno usklajevanje vseh posodobitev medsebojno odvisnih repozitorijev v
podatkovni bazi. Delovna enota je vodila seznam objektov, na katere so vplivale poslovne
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 85
transakcije. Prav tako je usklajevala zapis sprememb in razreševanje težav z vzporednim
dostopom.
Slika 6.22: Enota dela
6.2.2.3 Uporabniška dovoljenja in avtentikacija z digitalnim potrdilom
Izdelan spletni portal uporabljajo različne vrste uporabnikov, kateri imajo med seboj
različne pravice dostopa do določenih delov portala. Portal okvirno vsebuje naslednji
skupek uporabniških vlog, ki se dodeljujejo uporabnikom glede na njihove značilnosti
[16]:
administrator – upravitelj portala, ki lahko upravlja z uporabniki (dodeljuje,
odvzema pravice) ureja podatke v podatkovni bazi in podobno;
registriran uporabnik – registriran uporabnik brez posebnih pravic;
sodnik – uporabnik, ki lahko pregleduje plačilne naloge in
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 86
onemogočen uporabnik – uporabnik katerega račun je onemogočil administrator
portala zaradi določenih razlogov.
Avtentikacija uporabnika poteka v dveh korakih. Vedno, ko se uporabnik želi prijaviti v
portal spletni brskalnik prikaže okno za izbiro digitalnih potrdil. Uporabnik izbere lastno
digitalno potrdilo ter vpiše svoje uporabniško ime in geslo (Slika 6.23). V primeru, da se
serijska številka digitalnega potrdila ne ujema s serijsko številko potrdila uporabniškega
računa, ki je shranjen in asociiran v podatkovni bazi portala, portal izpiše obvestilo o
napaki, ki poziva uporabnika, da kontaktira z administratorjem portala (Slika 6.23). V
primeru, da pri prijavi ne pride do nobenih napak, uporabnika uspešno prijavi v sistem in
preusmeri na glavno stran portala [16].
Slika 6.23: Napaka pri prijavi v portal zaradi uporabe napačnega digitalnega potrdila
6.2.2.4 Izdelava administrativnega dela spletnega portala
Najbolj kompleksna in časovno potratna naloga je bila izdelava administrativnega dela
portala (Slika 6.24). Pri izdelavi administrativnega dela smo uporabili jQuery vtičnik
jTable, ki se je uporabljal za ustvarjanje tabel, ki temeljijo na AJAX-u (Asinhronemu
JavaScript-u in XML-ju). S pomočjo jTable smo prikazovali in manipulirali (CRUD
operacije) s podatki podatkovne baze spletnega portala [16].
Administracija je obsegala naslednja bistvena področja [16]:
administracija držav,
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 87
administracija občin in asociiranje občin s sodišči,
administracija in asociiranje naselij s poštami, ki so pristojne za določena
naselja,
administracija pošt,
administracija sodišč,
administriranje in asociiranje uporabnikov in uporabniških vlog,
asociiranje sodnikov.
Slika 6.24: Administracija uporabnikov
6.2.2.5 Čarovnik za oddajo evropskega plačilnega naloga
Za oddajo plačilnih nalogov smo ustvarili spletni čarovnik. Čarovnik je bil logično
razdeljen na štiri dele - korake [16]:
podrobnejši podatki o sodnem zahtevku,
osebni podatki o tožniku,
osebni podatki o tožencu,
predogled podatkov pred končno oddajo zahtevka (Slika 6.25).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 88
Uporabnik se je lahko prosto premikal že med vpisanimi koraki, če je pravilno vpisal vse
podatke določenega koraka. V primeru, da je uporabnik na določenemu koraku pustil
prazna ali napačno izpolnjena polja, so se na čarovniku izpisale napake. Prav tako se je
onemogočilo napredovanje v naslednji, višji korak čarovnika [16].
Slika 6.25: Zadnji korak čarovnika, ki omogoča predogled plačilnega naloga pred
dokončno oddajo
Na predzadnjem koraku čarovnika smo z uporabo JavaScript knjižnice jQuery pripravili
obrazec za oddajo PDF datotek. Obrazec je preveril ali je bila izbrana datoteka pravilne
velikosti (manjša od 5 MB) in pravilnega formata (PDF format). V primeru, da datoteka ni
bila primerna, se je pojavilo opozorilo o napaki. V nasprotnem primeru se je datoteka
naložila, ob uspešni oddaji sodnega zahtevka, torej po zaključku korakov čarovnika [16].
6.2.2.6 Izdelava strani za prikaz plačilnih nalogov izbranega sodnika
Dostop do sodniške sekcije portala (Slika 6.26) je bil dovoljen samo uporabnikom s
statusom sodnika. Sodnik je lahko pregledoval seznam sodnih nalogov, ki so mu bili
dodeljeni glede na specifično sodišče, v katerem je bil zaposlen. S klikom na posamezni
sodni nalog se je prikazala podstran, preko katere so bile vidne vse podrobnosti
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 89
posameznega sodnega zahtevka (Slika 6.27). S klikom na hiperpovezavo »Download« si je
sodnik lahko prenesel PDF datoteko preko katere je sodnik lahko nadaljnje obravnaval
izbrani sodni zahtevek (Slika 6.28). PDF datoteka je bila poimenovana z datumom oddaje
ter imenom vročitelja sodnega zahtevka [16].
Slika 6.26: Sodni zahtevki vezani na sodnika
Slika 6.27: Podrobnosti o izbranemu sodnemu zahtevku
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 90
Slika 6.28: Prenos PDF datoteke iz portala
6.3 Koristni pristopi in napotki za izgradnjo modernih ASP.NET MVC 4
aplikacij
Za lažje razumevanje in odločanje o uporabi posameznih metod in vzorcev, ki smo jih
uporabili tekom diplomske naloge, smo se v tabeli 3 odločili predstaviti najbolj ključne
napotke, metode in vzorce, ki se uporabljajo pri izgradnji modernih ASP.NET MVC 4
aplikacij.
Tabela 3: Koristni pristopi, metode in napotki pri izgradnji modernih aplikacij.
Ime metode Opis metode Namen in prednosti Kdaj uporabiti?
Tri-nivojska
arhitektura
Arhitektura, ki
omogoča ločevanje
zadev.
Aplikacija je
razdeljena na več
nivojev:
predstavitveni nivo,
nivo poslovne
logike in
nivo dostopa do
Ločevanje zadev.
Aplikacija s takšno
arhitekturo je robustna,
fleksibilna in ponovno
uporabna;
posamezni nivoji so
medsebojno neodvisni,
zato je spreminjanje in
uveljavljanje sprememb
v aplikaciji
enostavnejše;
V primeru izgradnje
kompleksnejše
aplikacije, katera bo v
prihodnosti potrebovala
nekoliko sprememb
in/ali različnih izvedb
za različne odjemalce
(spletne, namizne
aplikacije).
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 91
podatkov. izboljšana skalabilnost
in produktivnost
(vzporedni razvoj);
lažje uravnavanje
strežniške obremenitve;
redundantni
aplikacijski strežniki ;
zmanjšanje podvajanja
programske kode.
Šibka
sklopljenost
komponent
Komponente, moduli
aplikacije so med
seboj šibko povezani
preko vmesnikov v
takšni meri, da je
stopnja neposrednega
zavedanja med
komponentami
nadvse minimalna.
Zmanjševanje
soodvisnosti med
komponentami.
Zmanjševanje tveganja,
da bo uveljavljena
sprememba v okviru
posamezne komponente
posledično povzročila
nepričakovane
spremembe znotraj
ostalih šibko povezanih
komponent;
takojšna izolacija
napak;
v primeru napak,
poenostavljeno
testiranje;
enostavna ponovna
uporaba komponent;
izboljšana zmogljivost
delovanja, vzdrževanje
in odpravljanje napak;
povečanje fleksibilnosti
pri dodajanju,
odstranjevanju
komponent in
spreminjanju operacij v
okviru posamezne
komponente;
Primerno za aplikacije,
katerih ustrezno
delovanje mora ostati, v
primeru internih
sprememb, vedno
neokrnjeno.
Za aplikacije, katere
potrebujejo pri
delovanju visoko
stopnjo neodvisnosti
posameznih
komponent, tako da
lahko posamezne
komponente tekom
razvoja enostavno
dodajamo, spreminjamo
in odstranjujemo.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 92
varno eksperimentiranje
znotraj komponent.
Repozitorij
vzorec
Posrednik med
domenskimi in
podatkovnimi
objekti.
Zagotavlja abstrakcijo
nad dostopom do
podatkov.
Omogoča plast
abstrakcije (skrivanje
podrobnosti
implementacije dostopa
do podatkov) med
domensko logiko in
dostopom do podatkov
tako, da [16]:
promovira šibko
sklopljenost
posameznih plasti,
centralizira dostop do
objektov,
zmanjšuje podvajanje
kode (poizvedb),
omogoča boljšo
strukturo, preglednost
in vzdrževalnost kode
ter boljšo podporo za
testiranje enot.
Uporabno v aplikacijah,
ki imajo večje število
domenskih objektov,
nad katerimi vršimo
veliko število poizvedb.
V primeru, da se nad
večino domenskih
objektov vršijo podobne
operacije uporabimo
generični repozitorij.
Vzorec
Enota dela
Omogoča uporabo
skupnega objektnega
konteksta različnim
repozitorijem, ki so
del iste transakcije.
Omogoča usklajevanje
vseh posodobitev
medsebojno odvisnih
repozitorijev v shrambi
podatkov.
Vodi seznam objektov,
na katere vplivajo
poslovne transakcije in
Primerno za uporabo v
kompleksnih
večuporabniških
aplikacijah, katere
imajo večje število
medsebojno odvisnih
repozitorijev, kjer je
ažurnost in pravilen
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 93
usklajuje zapis
sprememb in
razreševanje težav z
vzporednim dostopom
[16].
vrstni poslovnih
transakcij izredno
pomemben.
Injiciranje
odvisnosti
Injiciranje odvisnosti
je tip obračanja
odvisnosti, kjer
premaknemo
nastanek in vezavo
odvisnosti izven
razreda.
Je programski
načrtovalski vzorec,
ki nam omogoča
razvoj šibko
sklopljenih modulov
programske opreme
[13].
Obračanje tipičnih
odvisnosti.
Ustvarjanje in vezava
odvisnosti se prenese
izven razreda na tretjo
osebo, najpogosteje na
DI zabojnik.
Izboljšana testabilnost
(uporaba oponašanih
objektov) in
vzdrževanost
aplikacije;
razvijalca spodbuja k
pisanju dobre, šibko
sklopljene programske
opreme.
Zelo uporabno v
povezavi s šibko
sklopljenimi
komponentami:
v primeru, da je
potrebno injiciranje
konfiguracijskih
podatkov v
komponente;
v primeru injiciranja
različnih
implementacij iste
odvisnosti.
Pri injiciranju istih
odvisnosti v več
različnih komponent.
Testno
usmerjen
razvoj
(TDD)
TDD zagotavlja, da
je končni izdelek v
skladu s potrebami in
zahtevami naročnika.
Prav tako pomaga, da
se upošteva obseg
funkcionalnosti in s
tem pomaga
razvijalcu razumeti,
Aplikacije zgrajene s
TDD tehniko so odprte,
razširljive in
prilagodljive. Injiciranje
odvisnosti je ključni del
TDD in arhitekture šibko
sklopljenih sistemov.
Takšen sistem je
robusten, enostaven za
Primerno pri
ustvarjanju
kompleksnih aplikacij s
kratkimi razvojnimi
iteracijami, kjer je
pomembno, da je
aplikacija robustna,
fleksibilna, modularna,
stabilna, kvalitetna in
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 94
kdaj bo resnično
konec z razvojem,
glede na trenutno
razvojno stanje
funkcionalnosti [4].
spremembe in odporen
proti napakam [4].
Zagotavlja kakovostno
kodo že od samega
začetka;
zagotavlja visoko
stopnjo povezanosti
med programsko kodo
in poslovnimi
zahtevami;
spodbuja komunikacijo
s poslovnim svetom;
pri ustvarjanju testov
se spodbuja interakcija
s poslovnimi
uporabniki, kar
omogoča pravilno
zasnovo testov in lažje
razumevanje grajenega
produkta;
pomaga ohranjati
neuporabljeno kodo
izven sistema;
zagotavlja vgrajeno
regresijsko testiranje;
preprečuje ponavljanje
ponavljajočih se napak.
razširljiva.
Uporablja se v navezi z
injiciranjem odvisnosti
in oponašalnimi objekti.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 95
7 SKLEP
S popularizacijo in čedalje večjo uporabo modernih tehnik razvoja aplikacij postajajo
aplikacije čedalje bolj fleksibilne, robustne in prijazne do sprememb. Z izdelavo praktične
aplikacije smo na samem primeru dokazali potencial in prednosti, katere prinaša
arhitektura gradnje šibko sklopljenih aplikacij. Zaradi šibko sklopljene arhitekture se lahko
v prihodnosti enostavno odločimo in zamenjamo implementacijo podatkovnega ali
uporabniškega nivoja z drugo implementacijo. Takšna modularnost je izredno priročna in
omogoča, da zamenjamo spletni vmesnik z drugim namiznim uporabniškem vmesnikom in
naenkrat aplikacija z bistveno manj truda postane namizna aplikacija. Morebitne napake se
zaradi prisotnosti testov enot lažje in hitreje odkrijejo. Takšna aplikacija je prilagodljiva,
robustna in lažje kljubuje zobu časa in spremenjenim zahtevam uporabnikov in različnim
trendom, ki se znajo spreminjati v prihodnosti.
Za lažje razumevanje in odločanje o uporabi posameznih metod in vzorcev, ki smo jih
uporabili tekom diplomske naloge, smo na koncu združili in predstavili najbolj bistvene
metode in vzorce, namen in prednosti ter ključne napotke kdaj uporabiti katero od metod,
ki se uporabljajo pri izgradnji modernih aplikacij tako, da smo novim in nadobudnim
razvijalcem olajšali prehod na nov način razvoja in ustrezno uporabo modernih tehnik
znotraj razvoja.
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 96
SEZNAM UPORABLJENIH VIROV
[1] A. F. S. Sanderson, Pro ASP.NET MVC 3 Framework, Apress, New York, 2011.
[2] B. Ganesan, ASP.NET MVC4: Bundling and Minification, Dostopno na:
http://www.codeproject.com/Tips/389545/ASP-NET-MVC4-Bundling-and-
Minification [31.7.2012].
[3] B. Martin, The Dependency Inversion Principle, Dostopno na:
http://www.objectmentor.com/resources/articles/dip.pdf [9.7.2012].
[4] J. M. J. Bender, Professional Test Driven Development with C#: Developing Real
World Applications with TDD, Wiley Publishing, Indianapolis, 2011.
[5] J. Palermo, ASP.NET MVC 4 in Action, Manning Publications, New York, 2012.
[6] J. Sonmez, Dependency Inversion, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-
sonmez&name=dependency-inversion&mode=live&clip=3&course=inversion-of-
control [9.7.2012].
[7] J. Sonmez, Inversion of control, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-sonmez&name=inversion-
of-control&mode=live&clip=1&course=inversion-of-control [11.7.2012].
[8] J. Sonmez, Basic to Basics: Understanding IoC Part 2 (Creation), Dostopno na:
http://simpleprogrammer.com/2010/11/30/basic-to-basics-understanding-ioc-part-
2-creation/ [12.7.2012].
[9] J. Sonmez, Dependency Injection, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-
sonmez&name=dependency-injection&mode=live&clip=5&course=inversion-of-
control [15.7.2012].
[10] J. Sonmez, Using Unity, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-sonmez&name=using-
unity&mode=live&clip=0&course=inversion-of-control [22.7.2012].
[11] J. Sonmez, Using Ninject, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-
sonmez&name=ninject&mode=live&clip=0&course=inversion-of-control
[25.7.2012].
[12] J. Sonmez, Using Structure Map, Dostopno na: http://www.pluralsight-
training.net/microsoft/players/PsodPlayer?author=john-
sonmez&name=structuremap&mode=live&clip=0&course=inversion-of-control
[25.7.2012].
[13] M. Seemann, Dependency Injection in .NET, Manning Publications, New York,
2011.
[14] M. Seemann, StructureMap PerRequest vs. Unique lifetimes, Dostopno na:
http://blog.ploeh.dk/2010/07/20/StructureMapPerRequestVsUniqueLifetimes.aspx
[25.7.2012].
[15] R. Gloor, Contextual binding, Dostopno na:
https://github.com/ninject/ninject/wiki/Contextual-Binding [25.7.2012].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 97
[16] R. Povodnik, Poročilo praktičnega izobraževanja v Cepris d.o.o., Maribor, 2012.
[17] S. Koirala, Design pattern – Inversion of control and Dependency injection,
Dostopno na: http://www.codeproject.com/Articles/29271/Design-pattern-
Inversion-of-control-and-Dependency [7.7.2012].
[18] S. Walther, ASP.NET MVC Framework Unleashed, Pearson education,
Indianapolis, 2009.
[19] Stackoverflow, Expression Tree Copy or Convert, Dostopno na:
http://stackoverflow.com/questions/4601844/expression-tree-copy-or-convert
[10.8.2012].
[20] Wikipedia, Dependency inversion principle, Dostopno na:
http://en.wikipedia.org/wiki/Dependency_inversion_principle [8.7.2012].
[21] Wikipedia, Mock object, Dostopno na: http://en.wikipedia.org/wiki/Mock_object
[6.8.2012].
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 98
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 99
Razvoj in testiranje spletnih aplikacij z uporabo ASP.NET MVC 4 Beta Stran 100