propell - hioastudent.cs.hioa.no/hovedprosjekter/data/2012/08/prosjektrapport.pdf · brukte jeg en...
TRANSCRIPT
PropellHovedprosjekt 2012 – Gruppe 8
av Øyvind Ingvaldsen (s161579)
HOVEDPROSJEKT
HOVEDPROSJEKTETS TITTEL
Propell
DATO
30. mai 2012
ANTALL SIDER / BILAG
94 / 3
PROSJEKTDELTAKERE
Øyvind Ingvaldsen (s161579)
INTERN VEILEDER
Larissa Sjarbaini
OPPDRAGSGIVER
Biip.no AS
KONTAKTPERSON
Erling Løken Andersen
SAMMENDRAG
Rapporten er satt sammen av to deler; produktdokumentasjon og prosessdokumentasjon.
Det anbefales å lese produktdokumentasjon først for å få en generell forståelse av systemet.
3 STIKKORD
Kunderelasjonshåndtering-system (CRM)
Webapplikasjon
ASP.NET MVC 3
Studieprogram: Informasjonsteknologi
Postadresse: Postboks 4 St. Olavs plass, 0130 Oslo
Besøksadresse: Holbergs plass, Oslo
PROSJEKT NR.
2012 – 08
TILGJENGELIGHET
Åpen
Telefon: 22 45 32 00
Telefaks: 22 45 32 05
Produktdokumentasjon
Produktdokumentasjon
1
Produktdokumentasjon
Innhold1 Innledning..........................................................................................................................................4
1.1 Propell........................................................................................................................................5
1.2 Mål.............................................................................................................................................5
1.3 Rotor..........................................................................................................................................5
2 Beskrivelse av Rotor..........................................................................................................................5
2.1 Design .......................................................................................................................................5
Innlogging..........................................................................................................................6
Salg....................................................................................................................................6
Kunder...............................................................................................................................7
Byråer................................................................................................................................9
Brukere............................................................................................................................10
Innstillinger......................................................................................................................11
2.1.1 Ikoner...............................................................................................................................12
3 Systemarkitektur..............................................................................................................................12
3.1 Løk-arkitektur..........................................................................................................................13
3.2 MVC........................................................................................................................................16
3.2.1 View models.....................................................................................................................16
3.3 Organisering av front-end-kode...............................................................................................17
3.4 Sikkerhet og autentisering.......................................................................................................19
Innlogging........................................................................................................................19
Utlogging.........................................................................................................................20
Autorisering.....................................................................................................................20
Autoriserings-annotasjonen.............................................................................................21
4 Teknologi.........................................................................................................................................21
4.1 Teknologien bak Propell..........................................................................................................21
4.2 Valg av teknologi for Rotor......................................................................................................23
4.3 Programmeringsspråk..............................................................................................................25
4.4 ASP.NET MVC 3.....................................................................................................................26
4.5 HTML og CSS.........................................................................................................................26
4.6 jQuery og jQuery UI................................................................................................................28
4.7 Ajax og JSON..........................................................................................................................31
2
Produktdokumentasjon
4.8 JsRender...................................................................................................................................32
4.9 Fluent NHibernate....................................................................................................................33
4.10 NUnit.....................................................................................................................................35
4.11 Ninject....................................................................................................................................36
4.12 AutoMapper...........................................................................................................................38
4.13 SQLite....................................................................................................................................39
4.14 Subversion.............................................................................................................................40
5 Dataarkitektur..................................................................................................................................40
5.1 Domene-modell ......................................................................................................................40
5.2 Kort beskrivelse av domene-entiteter......................................................................................42
Address............................................................................................................................42
Company..........................................................................................................................42
CompanyTrade.................................................................................................................42
ContactInfo......................................................................................................................42
MediaAgent.....................................................................................................................42
Note.................................................................................................................................42
Person..............................................................................................................................42
Project..............................................................................................................................42
Sale..................................................................................................................................43
SaleItem...........................................................................................................................43
SaleItemFormat................................................................................................................43
SaleItemType...................................................................................................................43
User..................................................................................................................................43
UserRole..........................................................................................................................43
6 Prosjektstruktur................................................................................................................................43
6.1 Prosjekter og avhengigheter.....................................................................................................43
Rotor.Domain..................................................................................................................44
Rotor.Infrastructure..........................................................................................................44
Rotor.Test.........................................................................................................................44
Rotor.Utils........................................................................................................................44
Rotor.Web........................................................................................................................44
6.2 Mappestruktur..........................................................................................................................44
3
Produktdokumentasjon
Rotor.Domain..................................................................................................................45
Rotor.Infrastructure..........................................................................................................46
Rotor.Test.........................................................................................................................47
Rotor.Web........................................................................................................................48
4
Produktdokumentasjon
1 InnledningDenne produktdokumentasjonen inneholder en beskrivelse av Rotor-systemet.
Produktdokumentasjonen er ment for personer som skal drive vedlikehold og
videreutvikling av systemet, den inneholder derfor en dypere beskrivelse av Rotor og
krever således en viss forståelse av relevante tekniske områder.
1.1 PropellPropell er et kunderelasjonsystem (CRM) utviklet av Biip.no. Det er utviklet på ASP.NET
3.5-rammeverket og benytter blant annet teknologier som NHibernate og jQuery.
1.2 MålMålet med oppgaven var å utvide Propell slik at det støttet ekstendering via plugins.
Oppdragsgiver ønsket også at Propell skulle kunne deles opp i moduler og slik at det kunne
selges som skreddersydde pakker med moduler.
Under rekognoseringsrfasen av prosjektet ble det oppdaget flere problemer med Propells
arkitektur og teknologi som ville gjøre videre utvikling vanskelig.
Det ble derfor bestemt at hele systemet skulle bygges opp på nytt med moderne teknologi
og med en arkitektur som ikke var til hinder for videre utvikling.
1.3 RotorDen nye systemet ble døpt til Rotor og skulle ha samme layout og funksjonalitet som
Propell.
2 Beskrivelse av RotorRotor er et web-basert kunderelasjonshånteringssystem (CRM-system). Produktet er
utviklet på ASP.NET MVC-plattformen og benytter jQuery og Ajax for å gi brukere en
interaktiv opplevelse.
5
Produktdokumentasjon
2.1 Design Da sluttbrukerne allerede var godt kjent med brukergrensesnittet i Propell, var det viktig at
jeg benyttet Propells brukergrensesnitt som mal for Rotor.
Siden grafisk designer ved bedriften skulle ta seg av farger og typografi, var min jobb
primært å sette opp layout. Jeg måtte da også sørge for at markup var definert på en slik
måte at den senere lot seg style uten større endringer.
Innlogging
Brukeren må her autentiseres for å få tilgang til systemet.
6
Produktdokumentasjon
Salg
Her holder systemet en full oversikt over alle salg gruppert etter status.
Brukere kan legge enkelt legge til salg. Ved hjelp av jQuery UI er for eksempel valg av dato
veldig enkelt.
7
Produktdokumentasjon
Kunder
Kundelisten lister alle kunder delt opp i tre grupper: kunder som den påloggede bruker har
relasjoner til, kunder som enda ikke har en relasjon til en selger, samt en liste over alle
kunder i systemet.
Det er like lett å legge til en ny kunde som det er å legge til et nytt salg.
8
Produktdokumentasjon
I bildet over er det bare to bransjer registrert. For å legge til en ny kan man trykke på
pluss-knappen bak bransje-valget. Man får da opp et lite form hvor man kan skrive inn et
nytt bransje-navn. Når man så lagrer det nye bransjenavnet vil bransje-valget med engang
få tilgang til den nye bransjet som ble lagt til, uten at siden krever en refresh.
Byråer
I listen over byråer får man oversikt over alle byråer med antall kontaktpersoner og
tilknyttede kunder.
På detaljesiden til hvert byrå kan man enkelt redigere informasjonen til byrået, legge til og
endre kontaktpersoner, og legge til notater.
9
Produktdokumentasjon
Brukere
På bruker-siden kan alle se en lite over brukere med navn, bilde og e-post. Administratorer
kan legge til nye brukere og redigere/slette brukere.
10
Produktdokumentasjon
Innstillinger
Administratorer har tilgang til en innstilling-side. Her settes generelle innstillinger for
systemet, her er en mer detaljert liste over brukere, og her er en liste over brukerroller.
Her er et skjermbilde fra rolle-listen. Med skjema for oppretting av en ny rolle.
Som nevnt skulle bedriftens egen designer style siden senere. Jeg valgte derfor å bare
sette opp et enkelt fargetema og sørge for at markup var skrevet på en måte som gjorde
det lett for designeren å style.
11
Produktdokumentasjon
2.1.1 IkonerJeg benyttet ikonene som er tilgjengelige fra jQuery UI. De var således konsistent med
utseendet til jQuery UI-temaet, og kunne enkelt endres ved å endre jQuery UI-tema.
En full liste over ikonene i jQuery UI kan ses i ThemeRoller1.
Til noen av linkene benyttet jeg favicon2 til sidene, som for eksempel verktøyboksen på
salg-sidene:
3 SystemarkitekturDa oppgaven i utgangspunktet var å gjøre at Propell bedre støttet endringer og utvidelser
brukte jeg en del tid i starten av prosjektet på å lese om systemarkitektur for web-
prosjekter.
Jeg ønsket å benytte en arkitektur for Rotor som gjorde det mulig å utvide systemet uten å
måtte foreta større refaktoriseringer av systemet.
Det er mange idéer når det gjelder organisering av større prosjekter og flere som spesielt
har vokst frem for å dekke behovet for systemer som enkelt kan vedlikeholdes og utvides.
Jeg ønsket også å benytte en arkitektur jeg kunne føle meg trygg på stod sterkt flere år
frem i tid, men in lieu av den hysteriske utviklingen innenfor informasjonsteknologi de
siste årene innså jeg at den perfekte arkitektur var en utopi; det som i dag er de facto
standard-arkitektur for større prosjekter, kan om noen år være brukt som skrekkeksempler
på dårlig arkitektur.
1 http://jqueryui.com/themeroller/ 2 http://en.wikipedia.org/wiki/Favicon
12
Produktdokumentasjon
Jeg føler fremdeles at de arkitekturelle valgene jeg til slutt landet på faller innenfor de
kriteria jeg satte. Løk-arkitekturen jeg senere skal beskrive har som hovedmål å løse opp i
de avhengigheter andre arkitekturer skaper, og avhengigheter er ofte kilden til problemene
som oppstår når man utvider eller endrer systemer.
3.1 Løk-arkitekturPropell var basert på en tradisjonell lagvis arkitektur hvor hvert lag i arkitekturen var
avhengig av laget under. Alle lagene var også avhengig av et hjelpelag (utility) med ofte
benyttede tjenester.
Propells arkitektur
Problemet med denne arkitekturen er avhengighetene den skaper. Hvert lag er avhengig av
alle lagene under. I Propells arkitektur er Web-laget avhengig av Biz-laget, som igjen er
avhengig av Data-laget. Web-laget er derfor transitivt avhengig av Data-laget.
Og transitive avhengigheter er fremdeles avhengigheter!
Et annet problem med denne arkitekturen er at den er data-sentrisk, noe som gjør større
endringer i Data-laget problematiske. Dette er ønskelig i et system som enkelt skal kunne
holdes moderne; det er historisk sett ofte endringer i data-aksess-teknologier.
Å få bort unødvendige avhengigheter mellom lag var et av hovedmålene jeg hadde ved å
finne en arkitektur for Rotor, jeg ønsket således å gå bort fra tradisjonelle lag-arkitekturen
Propell benyttet.
13
Produktdokumentasjon
Jeg fikk tips om en artikkel3 av Jeffrey Palermo hvor han beskriver det han kaller en løk-
arkitektur; en programvarearkitektur som lovet å løse noe av problemene den
tradisjonelle lag-arkitekturen skapte.
I løk-arkitekturen ser man på delene av prosjektet som lag i en løk. Hovedregelen for
avhengigheter er at alle lag bare kan ha avhengigheter som går innover mot kjernen av
løken; ellers kan et lag være avhengig av flere lag som er lengre innover mot kjernen.
3 http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
14
Produktdokumentasjon
Løk-arkitektur
Innerst i kjernen av løk-arkitekturen befinner domene-modellen seg. Den kan bare har
avhengighet til seg selv.
Like utenfor domene-modellen finner man et lag med domene-tjenester; her finner vi
repository interfaces: grensesnitt som beskriver henting og lagring av data.
Et veldig viktig poeng med arkitekturen er at selve implementasjonene av disse
grensesnittene ikke skal befinne seg i kjernen av applikasjonen; de skal implementeres helt
ytterst i arkitekturen (her i Infrastruktur-laget).
Andre lag i systemet skal kun benytte disse grensesnittene; det uten å i det hele tatt kjenne
til implementasjonene av dem. Det å endre dataaksess-teknologi blir så bare et spørsmål
om å lage nye implementasjoner av grensesnittene.
Et veldig positivt resultat av dette er at databasen flyttes fra selve kjernen av applikasjonen
ut i periferien, ergo den transitive avhengigheten som ofte går helt ned til databasen
fjernes.
Men hvordan kan disse repository interfacene implementeres og benyttes i andre deler av
lagene uten at lagene selv ikke vet om implementasjonene? Svaret her er en metode kalt
inversion of control4, nærmere bestemt via teknikken dependency injection.
Vanligvis når man koder må man klarere avhengigheter når man skriver (kompilerer)
koden. Skal du instansiere et objekt av typen X må du ha en referanse til kodefilen hvor X
er definert. Hvis du ikke har dette vil kompilatoren gi deg en feilmelding om manglende
referanse.
Med inversion of control klareres avhengigheter når programvaren kjøres i motsetning til
under kompilering. Dette gir rom for meget sofistikerte løsninger om det blir brukt
korrekt.
I Rotor er det benyttet dependency injection-rammeverket Ninject som gjør det veldig
enkelt å implementere inversion of control.
Da jeg startet prosjektet benyttet jeg MSSQL, men ønsket å prøve SQLite som et
alternativ. Takket være løk-arkitekturen var det å bytte database-teknologi så trivielt
som å implementere én ny klasse samt endre litt på Ninject-bindingene i bootstrapperen.
4 http://en.wikipedia.org/wiki/Inversion_of_control
15
Produktdokumentasjon
Jeg har med andre ord, bare i løpet av den lille tiden av prosjektet, fått erfare hvor godt
denne arkitekturen støtter infrastrukturelle endringer.
3.2 MVCMVC-mønsteret ble først formulert av professor emeritus ved UiO Trygve M. H. Reenskaug i 1979
da han jobbet for Xerox PARC.
MVC5 står for model-view-controller og er et mønster man kan benytte i utviklingen av
brukergrensesnitt. Med MVC-mønsteret deler man applikasjonen i tre ansvarsområder:
• Model – domeneobjekter6 og datastrukturer som definerer applikasjonens tilstand
• View – genererer output til bruker basert på applikasjonens nåværende tilstand
• Controller – håndterer bruker-input og utfører logikk på modellen
Hovedmotivet bak bruken av MVC-mønsteret er det klare skillet mellom domeneobjekter, logikk og
presentasjon; et veldig ettertraktet motiv som gjenspeiler seg i den utbredte bruken av MVC-
mønsteret i dagens programvareprosjekter.
Innen web-applikasjoner er MVC blitt veldig populært via rammeverk som Ruby on Rails,
ASP.NET MVC, Django7, Zend8 og CodeIgniter9.
Siden et av ønskene mine til Rotor var et sterkt skille mellom logikk og presentasjon, valgte jeg å gå
for ASP.NET MVC 3.0-plattformen.
3.2.1 View modelsI startfasene av prosjektet sendte jeg objekter fra domene-modellen direkte til strongly
typed views10. I viewet som listet alle salg sendte jeg en liste med Sale-objekter, i viewet
som viste detaljer om en bruker sendte jeg et enkelt User-objekt, etc.
Litt ute i prosjektet møtte jeg på noen problemer dog; på flere av sidene ønsket jeg
plutselig å ha flere enn ett domene-modell-objekt. På siden for å lage et ny bedrift ønsket
5 http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller 6 http://en.wikipedia.org/wiki/Domain_objects 7 https://www.djangoproject.com/ 8 http://framework.zend.com/ 9 http://codeigniter.com/ 10 http://www.howmvcworks.net/OnViews/BuildingAStronglyTypedView
16
Produktdokumentasjon
jeg for eksempel å hente ut en liste over mediebyrå ut slik at man kunne velge hvilket
mediebyrå bedriften skulle tilhøre.
Jeg fikk et tips fra en av utviklerne i bedriften om view models11 og det viste seg å være
løsningen på dette problemet (samt andre problem). Innenfor litteraturen kalles dette
mønsteret Model View ViewModel (MVVM), men jeg kommer til å referere til det som
view models.
Når du benytter view models lager du klasser som beskriver presentasjons-modellen til
views. I de enkleste tilfeller er en view model helt lik domene-modellen den er tilknyttet.
I Rotor har hver klasse i domene-modell en tilsvarende view model; for eksempel
Rotor.Domain.Sale og Rotor.Web.ViewModels.SaleViewModel. SaleViewModel har samme
felter som Sale, men inneholder også dataannotasjoner om feltene som blant annet
benyttes ved lagring og oppdatering av objekter.
3.3 Organisering av front-end-kodeI Propell var ikke front-end-kode (JavaScript) organisert på noe spesiell måte; JavaScript-
kode knyttet til en gitt side ble skrevet i presentasjonsfilen for den gitte siden. Jeg ønsket å
organisere front-end-koden bedre slik at det var enkelt å ha oversikt uten å måte lete rundt
i presentasjonsfilene. Jeg ønsket også en arkitektur hvor jeg hadde mest mulig kontroll
over rekkefølgen JavaScript-koden ble kjørt i.
Jeg kom over en artikkel12 av Paul Irish om det han først kalte markup-based unobtrusive
comprehensive DOM-ready execution. Han innså selv senere at navnet var litt klossete, og
døpte det så om til DOM-based Routing. Jason Garber utvidet idéen13 ved å benytte
HTML5 data-attributter14 (JavaScript-miljøet døpte hans iterasjon av idéen til Irish-
Garber-implementasjonen).
Idéen er ganske enkel og fungerer veldig bra med MVC-mønsteret; man organiserer
JavaScript-koden som en objekt literal15 med objekter med controller-navn og funksjoner
med action-navn.
11 http://en.wikipedia.org/wiki/Model_View_ViewModel 12 http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/ 13 http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution 14 http://html5doctor.com/html5-custom-data-attributes/ 15 https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Object_literals
17
Produktdokumentasjon
I body-en på dokumentet definerer man to HTML5-data-attributter; data-controller og
data-action med navn på action/controller. Et JavaScript henter denne informasjonen og
kaller så funksjonen som tilsvarer action/controller.
I koden over er ikke common en kontroller, men et objekt som kalles før alle andre
objekter. Her er det mulig å ha kode som trengs på alle sider. Metoden init er heller ikke
knyttet til et action-navn, men benyttet for kode som trengs på alle sidene til en gitt
kontroller. Dette er så klart frivillig, men som oftest veldig nyttig.
Det vi ønsker skal skje med koden over om vi for eksempel går på en side som kaller en
action kalt details i en kontroller kalt user, er at metodene i objektet automatisk skal bli
kalt slik:
Rotor.common.init
Rotor.user.init
Rotor.user.details
På denne måten organiserer man JavaScript på en måte som i aller høyeste grad
reflekterer strukturen på selve prosjektet, som for meg virket som den mest logiske måten
å organisere front-end-koden på. Det er også veldig oversiktlig og lett å refaktorisere
koden.
18
Produktdokumentasjon
For å unngå at disse action-metodene ble for store prøvde jeg å faktorisere mest mulig av
gjenbrukbar kode inn i en hjelpemodul i form av en jQuery-plugin16.
Jeg brukte namespaces for å ytterlig organisere koden innad i pluginen; jeg hadde for
eksempel namespacet $.Rotor.ui som inneholdt alle statiske funksjoner knyttet til
brukergrensesnitt, og namespacet $.Rotor.data som inneholdt statiske funksjoner knyttet
til henting av data (via Ajax).
Siden jeg ønsket et høyst interaktivt brukergrensesnitt og kraftig bruk av asynkron
oppdatering av deler av sidene til Propell, visste jeg det kom til å bli relativt mye koding i
JavaScript. Det var derfor imperativt at JavaScript-koden var organisert på en god måte
fra starten.
Jeg er meget fornøyd med bruken DOM-based routing samt jQuery-plugin, og følte at jeg
hadde god kontroll over JavaScript-koden takket være dette.
3.4 Sikkerhet og autentiseringPropell lagrer informasjon om en pålogget bruker i en HTTP-cookie17 i form av en kryptert
FormsAuthenticationTicket18.
Innlogging
Man logger inn via Login-action i Account-controlleren. Her oppgir man e-post og passord
som blir sendt til HTTP POST-versjonen av samme action.
Her sjekkes det først at en bruker med oppgitt e-post eksisterer. Om brukeren eksisterer
benytter den så den statiske metoden VerifyHash i
Rotor.Web.Authentication.HashService-klassen for å sjekke at passordet stemmer.
HashService-klassen utfører hashing19 ved hjelp av metoden
HashPasswordForStoringInConfigFile() i System.Web.Security.FormsAuthentication-
klassen.
Dette er en hjelpemetode som egentlig er ment for å hashe passord slik at hashen kan
lagres i en konfigurasjonsfil. Denne metoden kan dog fint benyttes til å hashe passord til
16 http://docs.jquery.com/Plugins/Authoring 17 http://en.wikipedia.org/wiki/HTTP_cookie 18 http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationticket.aspx 19 http://en.wikipedia.org/wiki/Hash_function
19
Produktdokumentasjon
lagring i en database, da alt den gjør er å hashe passordet og så konvertere det til et
base64-format20.
HashService-klassen benytter SHA1-algoritmen til hashing, og hasher passord med en salt21.
Om passordet som er oppgitt stemmer med det i databasen, opprettes det en
FormsAuthenticationTicket. Denne inneholder blant annet brukerens navn og id. Ticketen
krypteres så med metoden FormsAuthentication.Encrypt().
Videre opprettes det en HTTP-cookie som inneholder den krypterte ticketen og blir lagt til
i HTTP-responsen.
Utlogging
Utlogging skjer via Logout-action i Account-controlleren. For å logge en bruker ut fjernes
HTTP-cookien som ble opprettet ved innlogging. Man kan ikke direkte fjerne en HTTP-
cookie, men dette kan oppnås ved å lage en ny HTTP-cookie med samme navn og sette
ekspirasjons-datoen slik at cookien er gått ut.
Autorisering
Alle controllere i Rotor arver fra BaseController. Denne controlleren overskriver metoden
OnAuthorization() som blir kalt når en controller ønsker å autorisere brukeren.
I denne metoden blir HTTP-cookien hentet ut (om den eksisterer) og
FormsAuthenticationTicket-objektet blir dekryptert. Om ticketen eksisterer blir det
opprettet et RotorPrincipal og et tilhørende RotorIdentity-objekt.
Dette er implementasjoner av IPrincipal- og IIdentity-interfacene som er en viktig del av
sikkerhetsmodellen i .NET. Et IPrincipal-objekt beskriver sikkerhetskonteksten til en
pålogget bruker og IIdentity beskriver den påloggede brukerens identitet.
Disse objektene blir festet til den nåværende HTTP-konteksten; de er derfor tilgjengelig
gjennom resten av applikasjonen hvor man har tilgang på HTTP-konteksten.
I BaseController sendes så informasjon om den påloggede brukeren, samt informasjon
HTTP-requesten, til en enkel tjeneste kalt UserActionPermissionService. Denne sjekker
20 http://en.wikipedia.org/wiki/Base64 21 http://en.wikipedia.org/wiki/Salt_(cryptography)
20
Produktdokumentasjon
om brukeren som er pålogget har tilgang til siden.
Autoriserings-annotasjonen
Som sagt så arver alle controllere fra BaseController. Det utføres dog ingen form for
autorisasjon før man eksplisitt ber controlleren autorisere brukeren. I ASP.NET MVC 3
kan man enkelt gjøre dette ved å tilføre en data-annotasjon til enten en hel controller eller
en action. Data-annotasjonen-attributtet som fremtvinger en autorisasjon (i.e., kaller
OnAuthorization()-metoden) heter logisk nok [Authorize].
CompanyController har et Authorize-attributt som gjør OnAuthorization() blir kalt før
hver action.
4 TeknologiJeg ønsket å gjøre profesjonelle og nøye gjennomtenkte valg av teknologier til Rotor. Jeg
brukte således mye av tiden i planleggingsfasen til å bli kjent med aktuelle teknologier.
Det var så klart begrenset med tid jeg kunne benytte til å sette meg inn i disse, men jeg
ønsket sterkt å kunne forsvare de valgene jeg har tatt, samt kjenne til svakheter/styrker
med andre teknologier jeg ikke benyttet.
4.1 Teknologien bak PropellJeg var i den spesielle situasjonen at jeg hadde et fungerende system som skulle
gjenoppbygges, og hadde derfor en fase i starten hvor jeg satte meg inn i de teknologiske
valgene som allerede var gjort med Propell.
Selv om jeg hadde mye frihet ved valg av teknologi til Rotor, ønsket jeg så klart å gjenbruke
mest mulig kode fra Propell. Jeg satte meg derfor grundig inn i teknologiene bak Propell.
Propell var utviklet på Microsofts ASP.NET 3.5-plattform; all back-end-kode var skrevet i
21
Produktdokumentasjon
programmeringsspråket C# og benyttet seg av Code Behind-modellen22.
Code Behind-modellen baserer seg på at hver presentasjons-fil er knyttet til én enkelt
kode-fil som inneholder logikken for siden.
Code Behind-modellen ble sett på som et stort steg i riktig retning når det gjelder skille av
kode og representasjon fra den tidligere in-line-modellen hvor logikk-koden ble skrevet
direkte i presentasjons-filen, og modellen benyttes enda i stor grad.
Propell benyttet seg av flere forskjellige database-aksess-teknologier om en annen (dette
var virkelig forvirrende da jeg satte meg inn i Propell). Det var primært tre teknologier som
ble benyttet om en annen:
• SQL-kommandoer – sending av tekststrenger med SQL-queries direkte til serveren
• Stored procedures – kalling av lagrede prosedyrer på SQL-serveren
• ORM-rammeverket NHibernate23
Et ORM-rammeverk (object-relational mapping) er et rammeverk som mapper klasser
(vanligvis i en domene-modell) med strukturen i en database. ORM-rammeverk
abstraherer det meste av database-aksess også, som gjør det ekstremt enkelt å operere
mot databaser.
Foruten NHibernate benyttet Propells back-end seg av tredjeparts-bibliotekene Log4Net24
og AjaxPro25.
Log4Net er et bibliotek for å gjøre logging av applikasjoner enkelt. Det kan integreres lett
med NHibernate og benyttes derfor ofte hand-i-hand med NHibernate.
AjaxPro var et AJAX-rammeverk for ASP.NET 1.1 og ASP.NET 2.0. Utviklingen av
rammeverket stoppet i 2008, rundt tiden da Microsoft lanserte sitt eget AJAX-rammeverk26 for ASP.NET 2.0.
Propells front-end var utviklet med jQuery27 og jQuery UI28.
22 http://support.microsoft.com/kb/303247 23 http://nhforge.org 24 http://logging.apache.org/log4net/ 25 http://www.ajaxpro.info/ 26 http://www.asp.net/ajax 27 http://jquery.com/ 28 http://jqueryui.com/
22
Produktdokumentasjon
4.2 Valg av teknologi for RotorJeg ønsker i denne seksjonen å kort redegjøre for teknologiske valg jeg gjorde for Rotor.
Jeg går litt dypere inn i de bestemte teknologiene i neste seksjon.
Bedriften eneste definitive teknologiske krav for Rotor var at det skulle kunne kjøre på
deres Microsoft IIS-servere. Jeg bestemte derfor å holde meg til ASP.NET-plattformen.
For å kunne resirkulere deler av Propell på en behagelig måte var det uten tvil fordelaktig
at Rotor benyttet seg av samme programmeringsspråk som Propell. Jeg valgt derfor C#
som foretrukket språk for Rotors back-end.
Det har kommet flere nye teknologier til ASP.NET-plattformen siden utviklingen av
Propell startet i 2004; den mest interessante muligens lanseringen av ASP.NET MVC i
2009.
Selve hovedessensen i MVC-mønsteret er et sterkt skille mellom presentasjon og logikk (og
domene-modell), noe jeg var sterkt for å innføre i Rotor.
Jeg hadde en teoretisk forståelse av MVC-mønsteret og litt praktisk erfaring med MVC
innen web-utvikling via Ruby on Rails29. Ut i fra dette følte jeg også at MVC-mønsteret ville
gi mer vedlikeholdbar og lett-ekstenderbar kode i forhold til Code Behind-modellen som
var benyttet i Propell.
29 http://rubyonrails.org/
23
F#
Et av alternativene jeg her vurderte sterkt var F#; et multi-paradigme-språk utviklet
av Microsoft som har fått ordentlig plass i .NET-rammeverket fra og med Visual
Studio 2010.
Selv om F# også støtter flere paradigmer har F# sine røtter i funksjonelle språk (ML
og OCaml). jeg var veldig interessert i fordelene ved funksjonell programmering
kontra imperativ programmering og hadde gjerne ønsket å utnytte disse i Rotor.
F# har dog ikke helt funnet seg til rette i ASP.NET-verdenen; å lage et ASP.NET-
prosjekt i F# ville kreve litt tweaking og bruken av eksperimentelle funksjoner. Jeg
valgte derfor å gå for det tryggere og mye mer utbredte språket C#.
Produktdokumentasjon
Da jeg startet utviklingen var ASP.NET MVC 3.0 den nyeste stabile versjonen og jeg valgte
derfor å benytte det rammeverket (ASP.NET MVC 4.0 er i siste fasene av utviklingen og en
beta-versjon ble lansert i februar 2012).
I 2008 lanserte Microsoft sitt eget ORM-rammeverk; ADO.NET Entity Framework. De
første versjonene mottok mye dårlig kritikk, men i de senere versjonene har de ordnet opp
mange av kildene til kritikken, og vokst opp til et seriøst alternativ til andre ORM-
rammeverk.
I flere ASP.NET-MVC-bøker og eksempelprosjekter benyttes det Entity Framework; jeg
valgte dog å fremdeles benytte NHibernate slik som i Propell. Da hadde jeg både
tryggheten i NHibernates modenhet, samt masse eksempelkode fra Propell (med en
domene-modell jeg skulle resirkulere).
Det finnes uten tvil mange gode JavaScript-rammeverk til front-end. Da jeg startet
prosjektet valgte jeg fire populære rammeverk jeg ønsket å vite mer om slik at jeg hadde et
grunnlag til å kunne velge det beste rammeverket for Rotor.
De fire rammeverkene jeg vurderte var:
• jQuery (med jQuery UI)
• Dojo
• Prototype
• MooTools
Valg av JavaScript-rammeverk viste seg fort å være subjektivt; i de fleste tilfeller er det
snakk om personlige preferanser av syntaks. Det er så klart forskjell på størrelse, hurtighet
og funksjonalitet mellom rammeverkene, men dette er relativt små forskjeller og
rammeverkene har alle gode muligheter til ekstendering via plugins (samt veldig mange
tredjeparts-plugins).
24
Produktdokumentasjon
Valget falt til slutt på jQuery / jQuery UI fordi det
• er det mest utbredte rammeverket per i dag – stor brukerbase, mange plugins
• er veldig godt dokumentert30
• benytter CSS-selectors – kan utnytte (og utvide) allerede eksisterende kunnskap om
CSS
• gjør Ajax-kall veldig enkelt
• benyttes i Propell
Jeg visste at jeg ønsket å hente ut lister av for eksempel salg og vise dem i pene tabeller. Og
jeg ønsket at disse listene skulle kunne hentes asynkront via AJAX slik at kun listen
oppdaterte seg om man for eksempel slettet et element i listen. Det var (iallfall) to måter
jeg kunne oppnå dette på:
1. Kalle en AJAX-metode som henter ut elementene fra databasen og så returnerer en
liste med elementene i JSON-format – for og så generere tabellene prosedyrisk.
2. Kalle en AJAX-metode som henter ut elementene fra databasen og sender de til et
partial view som returneres.
Jeg valgte å bruke teknikk nr. 1 fordi jeg følte at det å få data i JSON-format gav meg mer
frihet.
Det eneste problemet med teknikken er at det er ganske krunglete å generere komplekse
DOM-elementer i jQuery. For å gjøre dette på en bedre måte valgte jeg derfor å bruke et
template-system for JavaScript kalt jsRender31.
4.3 ProgrammeringsspråkDe to programmeringsspråkene som ble benyttet under prosjektet var C# og JavaScript.
Jeg hadde svært liten erfaring med C#, men hadde tilbragt en god del tid med Java-kode.
Jeg visste at C# på flere måter kan beskrives som Microsofts svar på Java, og kjente meg
fort igjen i syntaksen da jeg startet å lese om C#.
30 http://api.jquery.com/ , http://docs.jquery.com/UI 31 https://github.com/BorisMoore/jsrender
25
Produktdokumentasjon
På bakgrunn av min erfaring med Java gikk det veldig fort å bli komfortabel med C#; de
gangene jeg kom over kode jeg ikke forstod var det som oftest knyttet til .NET-
rammeverket, men også her var det lett å se paralleller til Javas standard-bibliotek.
Javascript hadde jeg allerede en god forståelse av så det viste seg ikke å være noe problem.
På samme måte som ved C# vis-a-vis .NET var de fleste utfordringene i JavaScript knyttet
opp til jQuery.
4.4 ASP.NET MVC 3Web-applikasjon-rammeverket som ble benyttet var Microsofts ASP.NET MVC 3. Dette er
Microsofts bidrag blant MVC-baserte webapplikasjoner.
ASP.NET MVC ble sluppet i 2009, og har de siste årene opparbeidet et godt rykte på seg
blant webutviklere. ASP.NET MVC er integrert med eksisterende ASP.NET-funksjoner så
det har en viss grad av bakover-kompatibelt i forhold til prosjekter laget i «ren» ASP.NET.
ASP.NET MVC støtter flere forskjellige view-motorer, deriblant den populære motoren
Razor32.
I neste versjon av ASP.NET MVC kommer det også støtte for scaffolding33; script som
automatisk genererer innhold som gjør utviklingen av webapplikasjoner lettere.
I mars 2012 annonserte Microsoft at de hadde lansert ASP.NET MVC under åpen
kildekode (Apache License 2.0).
For å lære MVC 3 fulgte jeg et video-kurs34 av K. Scott Allen på Pluralsight og kjøpte boken
Pro ASP.NET MVC 3 Framework35 av Steven Anderson og Adam Freeman.
4.5 HTML og CSSOppdragsgiver ønsket at deres interne grafiske designer skulle kunne sette opp styling og
typografi på et senere tidspunkt. Min oppgave var derfor først å fremst å sette opp
sidens layout (med Propell som mal).
32 http://en.wikipedia.org/wiki/Microsoft_ASP.NET_Razor_View_Engine 33 http://en.wikipedia.org/wiki/Scaffold_(programming) 34 http://www.asp.net/mvc/pluralsight 35 http://www.amazon.com/gp/product/1430234040
26
Produktdokumentasjon
HTML36 (HyperText Markup Language) er et markeringsspråk for å formatere nettsider;
dets primære bruksområde være å strukturere nettsider. Den nyeste standarden er HTML
4.01 og ble lansert i 1999. En XML-basert37 ekstensjon av HTML, XHTML38, ble lansert i
1998 og ble i 2000 anbefalt til bruk av nettside-strukturering av World Wide Web
Consortium (W3C).
De siste årene har det i webutviklingsmiljøet vært mye snakk om den nye HTML-
standarden som er under utvikling; HTML539. Denne versjonen skal ta over for både
HTML 4.01 og XHTML 1.1. Den nye standarden prøver å løse flere problemer; blant annet
en mye bredere støtte for multimedia-elementer og grafikk.
Et annet problem HTML5-standarden adresserer er mangelen av semantisk innhold på
nettsider. Med dagens standard forstår en datamaskin hvordan den skal presentere en
nettside i nettleseren, men den forstår sjeldent hva den presenterer og forholdet mellom
det strukturelle elementene den presenterer.
HTML5-standarden ønsker å løse noe av dette ved å innføre tags og attributter som
inneholder metadata om innholdet; standarden inneholder blant annet tags som <header> og <footer> som kan benyttes for å spesifisere topp- og bunntekst til en side (eller en
seksjon av siden).
Denne innføringen av semantiske innhold i markupen er en del av initiativet Semantic
Web40 som ble startet av Sir Tim Berners-Lee41; oppfinneren av World Wide Web og
direktør for World Wide Web Consortium.
Selv om HTML5-standarden fremdeles er under utvikling, støtter de fleste nye nettlesere
en majoritet av de nye elementene i HTML5. Jeg valgte derfor å benytte HTML5 i Rotor.
Som de fleste web-utviklere har fått erfare er det dessverre én nettleser som vanligvis
kommer for sent til festen; Microsofts Internet Explorer. Nettleseren har mistet betydelig
markedsandel i løpet av de siste årene42 (til fordel for Google Chrome og Mozilla Firefox),
men har uten tvil forbedret seg når det gjelder støtte av standarder.
36 http://en.wikipedia.org/wiki/HTML 37 http://www.w3.org/XML/ 38 http://www.w3.org/TR/xhtml1/ 39 http://en.wikipedia.org/wiki/HTML5 40 http://www.w3.org/standards/semanticweb/ 41 http://en.wikipedia.org/wiki/Tim_Berners-Lee 42 http://www.w3schools.com/browsers/browsers_stats.asp ,
http://en.wikipedia.org/wiki/Usage_share_of_web_browsers
27
Produktdokumentasjon
Fra og med versjon 9 støtter Internet Explorer HTML5-elementer. Det er dessverre enda
en del som benytter tidligere versjonen av Internet Explorer, men dette kan fikses lett
med det lille JavaScriptet html5shiv43 og en liten kodesnutt i toppen av siden:
Layout av siden ble gjort med CSS44 (Cascading Style Sheets). I en liknende situasjon som
ved HTML5-standarden er en ny og meget interessant versjon av CSS under utvikling
(CSS3). Denne inneholder mange nye funksjoner som for eksempel avrundede hjørner på
bokser, skygger, web-fonts og animasjoner.
Dog da jeg primært bare skulle fokusere på plasseringen av elementer hadde jeg det jeg
trengte i den nåværende versjonen av CSS og benyttet ingen av de nye eksperimentelle
funksjonene i CSS3.
CSS-standarden ble forøvrig først foreslått av nordmannen Håkon Wium Lie.
4.6 jQuery og jQuery UIjQuery er et veldig populært JavaScript-rammeverk som forenkler operasjoner som for
eksempel HTML DOM-manipulasjon, animering, håndtering av hendelser og Ajax-
interaksjon. jQuery er veldig godt dokumentert og har et stort bibliotek av tredjeparts-
plugins45.
Når du ønsker å velge DOM-elementer46 med jQuery kan du sende en tekststreng med en
CSS-selector til funksjonen jQuery() - eventuelt det kortere aliaset $(). Denne funksjonen
returnerer så et jQuery-objekt som representerer elementene du valgte.
Dette er veldig praktisk siden du kan utnytte tidligere kunnskap om CSS når du bruker
jQuery; skal du for eksempel ha tak i alle linker på en side som linker til en Wikipedia-side
kan du benytte følgende kode som gir deg et jQuery-objekt med elementene:
43 http://code.google.com/p/html5shiv/ 44 http://www.w3.org/Style/CSS/ 45 http://plugins.jquery.com/ 46 http://www.w3schools.com/htmldom/default.asp
28
Produktdokumentasjon
Her benytter vi en CSS-selector som sier: velg alle <a>-elementer hvor href-attributten
starter med teksten «http://en.wikipedia.org».
En annen designmessig godbit fra jQuery er at de fleste metodene til jQuery-objektet
returnerer selve objektet det kalles på; dette gjør det mulig å «chaine» metode-kall:
Her velger vi et element med id-en «mybox». Vi endrer så teksten i elementet, fjerner en
CSS-klasse, legger til en CSS-klasse og setter bredden på elementet til 100 piksler.
jQuery gjør det enkelt å håndtere hendelser (som for eksempel museklikk, endring av valg i
dropdown-lister o.l.) ved at man enkelt kan definere callbacks47 som blir kalt ved
hendelser. jQuery-metoden click() benyttes for å binde en callback-metode til et
museklikk:
Her velger vi alle paragraf-elementer og binder en (anonym) funksjon til
museklikkhendelsen. I dette tilfelle velger vi å gjemme paragraf-elementet om det blir
klikket på.
Et annen tiltrekkende egenskap ved jQuery er Ajax-funksjonene det tilbyr.
Hovedfunksjonen er $.ajax(). Denne tar i mot et sett med nøkker-verdi-par med
alternativene til Ajax-kallet; deriblant callback-funksjoner som kalles når data mottas fra
serveren (eventuelt en feilmelding mottas).
47 http://en.wikipedia.org/wiki/Callback_(computer_programming)
29
Produktdokumentasjon
jQuery tilbyr også fem kort-versjoner av $.ajax()-funksjonen som er ferdig konfigurert:
• $.get() - ferdig konfigurert for en HTTP GET-request
• $.post() - ferdig konfigurert for en HTTP POST-request
• $.getJSON() - ferdig konfigurert for en HTTP GET-request som mottar data i JSON-
format
• $.getScript() - laster (og så kjører) et JavaScript via en HTTP GET-request
• .load() - en metode på jQuery-objektet som laster data fra server og plasserer det i
DOM-elementet/elementene som jQuery-objektet matcher. Om det er spesifisert
data til serveren blir det kalt via en HTTP POST-request, ellers en HTTP GET-
request
Takker være disse hjelpemetodene krever det veldig lite kode for å gjøre Ajax-kall. Og om
du trenger full kontroll over Ajax-kallet har man alltids $.ajax()-metoden hvor man kan
spesifisere alle alternativer.
Når elementet med id «getinfo» blir trykket på så blir det sendt en HTTP GET-request til
URL-en «/getinfo». Data som returneres fra denne URL-en blir så sendt til elementet
med id «infobox».
jQuery UI er et rammeverk for å lage nettsider med interaktive brukergrensesnitt. Det ble
lansert i 2007 og er utvikles av samme folkene som står bak jQuery.
jQuery UI inneholder mange widgets som er klare til bruk; deriblant knapper, dialog-
vinduer, dato-velgere og bokser med faner. jQuery UI kan også gjøre det enkelt å la
brukere endre størrelse på DOM-elementer samt enkelt sette opp dra-og-slipp-
funksjonalitet på nettsiden.
30
Produktdokumentasjon
Så enkelt er det å gjøre slik at elementet med id «dragme» kan dras rundt på nettsiden.
jQuery UI har også innebygde animasjoner og animasjonsmuligheter; som foreksempel å
lage en animasjon ved å interpolere mellom to CSS-klasser over en gitt tid.
jQuery UI er modul- og tema-basert. På nedlastningssiden48 kan du selv velge hvilke
komponenter du ønsker skal være med når du laster det ned. At det er tema-basert gjør at
du enkelt kan endre tema bare ved å velge en annen CSS-fil for jQuery UI.
Det gjør det også enkelt å style jQuery UI-elementene til å passe til en gitt nettside. På
jQuery UI-nettsiden finnes det en ThemeRoller49 hvor du, i nettleseren, kan definere og
laste ned ditt eget jQuery UI-tema.
4.7 Ajax og JSONSom tidligere nevnt ønsket jeg at deler av Rotor-sidene skulle kunne oppdateres asynkront.
Det mest brukte verktøyet for dette problemet er per i dag Ajax. Ajax er ikke en ny
teknologi, ei heller én enkelt teknologi: det er en gruppe av teknologier som gjør det mulig
å sende HTTP-requester til serveren asynkront.
Hovedteknologien bak Ajax stammer fra Microsofts ActiveX-kontroll50 XMLHTTP, og ble
lansert med Internet Explorer 5 i 1999. Andre nettlesere implementerte dette senere som
et innebygd JavaScript-objekt kalt XMLHttpRequest. Microsoft fulgte så etter de andre
nettleserne ved å benytte XMLHttpRequest-objektet fra og med Internet Explorer 7 (dog
ActiveX-kontrollen kan fremdeles benyttes).
For å gjøre et Ajax-kall i JavaScript må man manuelt opprette et XMLHttpRequest-objekt
(eventuelt et ActiveX XMLHTTP-objekt om det er Internet Explorer 6 eller 7), sende det til
serveren, og så handle basert på statusen til requesten. Det kreves altså litt kode for å gjøre
dette, men heldigvis har de fleste store JavaScript-rammeverk hjelpefunksjoner for å
utføre Ajax-kall.
48 http://jqueryui.com/download 49 http://jqueryui.com/themeroller/ 50 http://en.wikipedia.org/wiki/ActiveX
31
Produktdokumentasjon
For at Ajax-funksjonaliteten skal fungere må så klart server-siden også ha Ajax-støtte.
ASP.NET MVC 3 støttet dette helt smertefritt: man kan kalle en action-metode på en
controller via Ajax-kall på samme måte som et vanlig request.
JSON51 (JavaScript Object Notation) er en tekst-basert åpen standard for strukturering av
data. Den ble utviklet med mål å være mer lesbar og mindre verbose52 en alternative
formater (primært XML). Selv om strukturen til JSON er basert på JavaScript-objekter er
ikke JSON knyttet til JavaScript; det benyttes i mange språk. Spesielt innen sending av
data mellom web-servere og web-applikasjoner har JSON fått solid fotfeste de siste årene.
En av årsakene til at jeg valgte å bruke JSON fremfor XML til data var at jQuery benyttet
JSON til sending av data til serveren. Det virket bedre og mer konsistent om data jeg
mottok fra serveren var i samme format.
En annen årsak var hvor enkelt det er å serialisere data til JSON-format i ASP.NET MVC 3.
Om jeg for eksempel hentet ut en liste over alle salg fra databasen trengte jeg bare å kalle
Json() metoden i controlleren med listen over salg som argument. Den returnerte da et
korrekt strukturert JSON-objekt med alle salgene i.
4.8 JsRenderJeg nevnte tidligere at det å bygge opp komplekse DOM-elementer som tabeller er
krunglete med jQuery. Verktøyet jeg valgte for å gjøre dette enklere var template-systemet
JsRender.
Med JsRender definerer du templates i HTML-format med tags som kan erstattes med
data. Tagene kan inneholde JavaScript-kode eller navnet på en nøkkel i et JSON-objekt.
JsRender støtter også konstrollstrukturer som if-then-else og for-each.
51 http://www.json.org/ 52 http://www.thefreedictionary.com/verbose
32
Produktdokumentasjon
For å bruke et template kaller du bare metoden render() på templatet hvor du eventuelt
oppgir data i JSON-format. Om JSON-objektet du sender er en liste med objekter kjøres
templatet én gang for hvert objekt.
Selv om JsRender er i beta-stadiet og er litt eksperimentelt har det mottatt mye god kritikk
fra web-utvikler-miljøet. Jeg valgte derfor å benytte dette i Rotor.
Alternativene, som tidligere nevnt, ville vært å enten generere HTML-strukturen med
jQuery eller få data i ferdig HTML-format fra serveren (ved å benytte partial views i
ASP.NET MVC 3).
4.9 Fluent NHibernateNHibernate er en .NET-port av det populære ORM-rammeverk Hibernate53 for Java.
Hibernate har historie helt bak til 2001 mens utviklingen av NHibernate startet i 2005.
NHibernate er et ORM-rammeverk så dets hovedoppgave er å mappe klasser i en domene-
modell til en (relasjons-) database. Resultatet er at utvikleren enkelt kan jobbe mot rader i
databasen som om de var objekter i kildekoden.
Om du for eksempel skal lagre en ny bruker i databasen ville det tradisjonelt kreve at du
kjenner til database- og dataaksess-teknologien til den gitte databasen. Du måtte også
manuelt skrive kommandoer som lagret brukerens attributter i tilsvarende kolonner, og
sørge for at datatypene til brukeren matchet datatypene databasen støttet.
Med et ORM-rammeverk som NHibernate kan det å lagre en ny bruker være så enkelt som
å opprette et bruker-objekt og sende det til en save()-metode som rammeverket
supplementerer.
53 http://www.hibernate.org/
33
Produktdokumentasjon
For at dette skal fungere må NHibernate vite hvordan det skal mappe klassene;
NHibernate benytter her xml-filer hvor du må spesifisere mappingen til hver enkelt klasse:
Eksempel på NHibernate-mapping-fil fra Propell.
Det å definere mappingen er noe man gjør én gang og sjeldent endrer fordi den er knyttet
til domene-modellen (som sjeldent bør endres).
Et alternativ til den tradisjonelle XML-baserte mappingen er Fluent NHibernate54. Med
Fluent NHibernate kan du skrive mappingen i C#-kode. En klar fordel med dette er at
koden er strongly typed som gjør eventuelle endringer i mappingen mye lettere å
håndtere. C#-koden er også lettere å lese enn XML-formatet, da det inneholder mindre
betydelig mindre navn og symboler.
Eksempel på Fluent Nhibernate-mapping fra Rotor. Koden mapper samme klasse som
over, men er betydelig mindre og enklere å lese.
54 http://www.fluentnhibernate.org/
34
Produktdokumentasjon
Om man fremdeles skulle mene at dette er for tungvindt har Fluent NHibernate støtte for
Auto Mapping55. Man sier bare til Fluent NHibernate hvor domene-modellen befinner seg
og det mapper automatisk alle klassene. Du kan eventuelt spesifisere konvensjoner for
hvordan det skal mappes og kan legge til unntak og egne regler for bestemte klasser.
Jeg benyttet meg ikke av Auto Mapping i Rotor da jeg ønsket full kontroll over mappingen
(spesielt hvordan cascading skulle håndteres).
4.10 NUnitTil testing valgte jeg å bruke rammeverket NUnit, det selv om Microsoft tilbyr et eget
rammeverk for unit testing. NUnit er en del av av xUnit-familien – en betegnelse brukt om
teste-rammeverk som opprinnelig baserer seg på SUnit56.
Det er laget xUnit-rammeverk til veldig mange programmeringsspråk57 og det så jeg på
som en stor fordel da jeg skulle velge test-rammeverk.
Når det er sagt er Microsofts test-rammeverk uten tvil opp til par med NUnit. Spesielt
hvis du benytter mocking-rammeverket58 Moq59.
Den, for meg, største forskjellen på Microsofts test-rammeverk og NUnit var at Microsofts
rammeverk er integrert i Visual Studio mens NUnit-tester kjøres via et eget program. Jeg
likte at det var helt integrert og at jeg for eksempel kunne trykke CTRL-R, T for å kjøre
tester.
NUnit-programmet kommer i to varianter; en konsoll- og en GUI-versjon. Jeg benyttet
primært GUI-versjonen. Å kjøre testene var veldig enkelt i NUnit. Alt jeg måtte gjøre var å
peke til DLL-filen til prosjektet og så kom alle testene opp i GUI-et. Her kunne jeg enkelt
kjøre tester.
55 https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping 56 http://sunit.sourceforge.net/ 57 http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks 58 http://en.wikipedia.org/wiki/Mock_object 59 http://code.google.com/p/moq/
35
Produktdokumentasjon
Hovedvinduet til NUnit. Alle testene i NHibernate_MediaAgent_Test gikk gjennom.
En av test-metodene i Authentication_Test feilet.
Jeg ønsket å ikke operere direkte mot en «live» database da jeg kjørte tester. Dette var
heldigvis veldig enkelt å gjøre med Fluent NHibernate; man bare endret kodelinjen som
spesifiserte databasefilen og endret det til InMemory(). Man fikk da en midlertidig database
i minnet som fungerte akkurat som en vanlig database.
4.11 NinjectNinject er et rammeverk for dependency injection. Dependency injection er en teknikk
man kan utilisere for å unngå avhengigheter mellom klasser. Istedet for å benytte instanser
av andre klasser i en klasse, bruker man interfaces og lar rammeverket binde interfacene til
implementasjoner av klasser ved runtime.
Ninject gjør dette enkelt og tilbyr flere injeksjons-mønstre; den vanligste være
36
Produktdokumentasjon
konstruktør-injeksjon. Man spesifiser da en en konstruktør som tar en eller flere interfaces
som argumenter. Når man lager en ny instans av klassen vil Ninject-kjernen binde de
interfacene til implementasjoner basert på NinjectModulene som kjernen benytter.
I Rotor var det primært ett interface jeg brukte dependency injection for;
Rotor.Domain.Service.IRepository. Dette var interfacet som applikasjonen benyttet når
det var behov for å kommunisere med databasen.
IRepository definerer metoder for kommunikasjon med database. Istedet for å ha ett
repository-interface for hver klasse i domene-modellen benytter IRepository generics60.
Skal du for eksempel hente ut alle brukere kaller du repository.All<User>() (hvor
repository er en instans av IRepository-interfacet).
Ved å benytte dette interfacet og ha implementasjonen av det helt «ytterst» i arkitekturen,
var applikasjonen helt uavhengig av hvordan interfacet var implementert. Jeg
implementerte dette interfacet senere i klassen:
Rotor.Infrastructure.NHibernate.Service.NHRepository. Denne benyttet NHibernate
til kommunikasjon med en SQLite database.
Jeg instruerte så Ninject at det skulle binde IRepository til NHRepository:
60 http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
37
Produktdokumentasjon
NinjectModulen som Rotor benytter.
I en MVC-applikasjon er det i controllerene logikken ligger, og det er derfor her jeg hadde
behov for et IRepository. Heldigvis har utvikleren av Ninject laget en MVC-ekstensjon61 til
Ninject. Denne integrerer Ninject i en MVC-applikasjon og gir controllere automatisk
muligheten til å bruke konstruktør-injeksjon.
Alt jeg trengte å gjøre i controllerene var å lage en konstruktør som tok et IRepository som
argument og ta vare på dette til senere bruk:
Ved hjelp av Ninject og NinjectModulen over blir IRepository gjort om til et
NHRepository ved kjøring. Det uten at MediaAgentController i det hele tatt vet om
NHRepository.
Ninject er uten tvil et kraftig verktøy og gir deg muligheten til å skrive uavhengig kode som
fungerer.
4.12 AutoMapperAutoMapper62 er et enkelt lite bibliotek med ett arbeidsområde: mappe mellom objekter.
AutoMapper gjør bruken av view models veldig mye lettere fordi det enkelt kan settes opp
til å mappe mellom klassene i domene-modellen og view models.
61 https://github.com/ninject/ninject.web.mvc 62 https://github.com/AutoMapper/AutoMapper
38
Produktdokumentasjon
Action-metoden som mottar data fra et form i Create-viewet.
MediaAgentViewModel inneholder dataannotasjoner så vi benytter ModelState.IsValid
for å sjekke at data som er supplementert via formet er korrekt. Vi oppretter så et
MediaAgent-objekt og bruker AutoMapper til å mappe data fra MediaAgentViewModel
inn i det nye MediaAgent-objektet som vi videre lagrer i databasen via et IRepository-
objekt.
4.13 SQLiteI starten brukte jeg en lokal MSSQL-server, men byttet senere til SQLite63. SQLite er en
liten, server-løs SQL-database-motor som ikke krever noen konfigurasjon. SQLite støtter
SQL-standarden, oppfyller ACID-kravene64 og lagrer hele databasen i én enkelt fil.
SQLite-motoren krever ikke en server fordi det ikke kjører som en egen prosess som klient-
prosessen kontakter, men er integrert som en del av selve klient-prosessen.
SQLite er veldig populær fordi det er veldig enkelt å deployere en applikasjon som benytter
SQLite. På grunn av sin lille størrelse er SQLite også populær på mindre datasystemer som
for eksempel på mobiltelefoner.
Den største begrensningen til SQLite er at den låser database-filen under skriving; da
skrivinger som oftest ikke tar lang tid vil ikke dette være et problem med mindre du må ha
muligheten til å utføre flere hundre skrivinger i sekundet.
Databasefilen blir ikke låst under lesing så flere kan lese på samme tid uten problem.
Jeg valgte å benytte SQLite til Rotor fordi det gav Rotor en enklere deployerings-prosess
63 http://www.sqlite.org/ 64 http://en.wikipedia.org/wiki/ACID
39
Produktdokumentasjon
uten å påvirke kvaliteten.
4.14 SubversionSubversion er versjonskontrollsystemet jeg benyttet under prosjektet. Jeg fikk opprettet et
Subversion-repository på serveren til bedriften og benyttet Visual Studio-pluginen
AnkhSVN65 som gir integrert støtte for Subversion i Visual Studio.
5 Dataarkitektur
5.1 Domene-modell Da jeg hadde en allerede fungerende domene-modell trengte jeg ikke planlegge og bygge
opp database-strukturen fra scratch. Det var heller ikke noe behov for å normalisere
databasen; de som bygget opp Propell hadde allerede gjort en god jobb.
Strukturen som var benyttet til Propell var allerede på BCNF-form66, som jeg anser som
kvalifisert som en god database-struktur.
65 http://ankhsvn.open.collab.net/ 66 http://en.wikipedia.org/wiki/Boyce%E2%80%93Codd_normal_form
40
Produktdokumentasjon
41
Produktdokumentasjon
5.2 Kort beskrivelse av domene-entiteter
Address
Beskriver en fysisk postadresse. Inneholder felter for to adresselinjer, postboks, område og
land.
Company
En bedrift (kalt en kunde i Rotor) med navn, organisasjonsnummer og
kontaktinformasjon. En bedrift er knyttet til en bransje og kan ha flere kontaktpersoner.
Kan være tilknyttet et mediebyrå.
CompanyTrade
En bransje med et unikt navn. En bedrift opererer innenfor en bransje.
ContactInfo
Inneholder kontaktinformasjon (som for eksempel telefon og e-post). Kan ha referanse til
to adresser; den andre bruker for eksempel når besøksadresse ikke er lik post-adresse.
Både bedrifter, mediebyrå og prosjekter har kontaktinformasjon.
MediaAgent
Et mediebyrå er i utgangspunktet som en bedrift, men har også informasjon om provisjon.
Note
Et notat har innhold, en bruker som har laget det og datoen det ble laget. Andre entiteter
har en liste med notater om den entiteten.
Person
Personer er registrert som kontaktpersoner hos enten mediebyråer eller bedrifter. En
person kan være kontaktperson for flere bedrifter/byrå.
Project
Et prosjekt brukes for å gruppere brukere og salg i Rotor.
42
Produktdokumentasjon
Sale
Et salg med informasjonen om salget og en liste salgselementer.
SaleItem
Representerer en «salgslinje» i et salg. Inneholder informasjon om type, format, antall,
brutto/netto sum og rabatt.
SaleItemFormat
Et format et SaleItem kan ha. Har et unikt navn.
SaleItemType
En type et SaleItem har. Har et unikt navn.
User
Beskriver en bruker i Rotor-systemet. Er knyttet til et prosjekt og en brukerrolle.
UserRole
En brukerrolle er en navngitt beskrivelse av rettigheter for hver del av Rotor.
6 Prosjektstruktur
6.1 Prosjekter og avhengigheterProsjektet består av en Vistual Studio-solution som inneholder fem prosjekter.
43
Produktdokumentasjon
Rotor.Domain
Dette prosjektet inneholder domene-modellen og domene-tjenester.
Rotor.Infrastructure
Inneholder klasser som er direkte knyttet til teknologier for dataaksess.
Implementasjonene av domene-tjenestene finnes for eksempel i dette prosjektet.
Rotor.Test
Prosjektet for alle unit tester. Benytter seg av NUnit-rammeverket.
Rotor.Utils
Inneholder hjelpeklasser og -metoder som er aksesable over hele prosjektet.
Rotor.Web
Selve inngangsportalen til applikasjonen og inneholder all UI-kode via ASP.NET MVC 3-
rammeverket.
6.2 MappestrukturHer er en beskrivelse av mappene i hvert prosjekt.
44
Produktdokumentasjon
Rotor.Domain
• Enums – inneholder enums67 som benyttes i domene-modell-entitetene.
• Model – inneholder klassene som definerer entitetene i domene-modellen.
• Service – inneholder domene-tjenester; f.eks. interfaces som beskriver dataaksess.
67 http://en.wikipedia.org/wiki/Enumerated_type
45
Produktdokumentasjon
Rotor.Infrastructure
• NHibernate
◦ Mappings – her ligger Fluent NHibernate-mappingene av domene-entitetene.
◦ Service – inneholder NHibernate-implementasjoner av domene-tjenester.
46
Produktdokumentasjon
Rotor.Test
• Authentication – tester av autentisering og autorisering
• NHibernate – tester av NHibernate-rammeverket
47
Produktdokumentasjon
Rotor.Web
• Authentication – klasser som har med autentisering og som er direkte knyttet til
MVC-rammeverket
• Content
◦ css – alle CSS-filer ligger her.
48
Produktdokumentasjon
◦ img – bilder, som for eksempel ikoner og logoer.
◦ js – alle JavaScript-filer, inkluderte tredjeparts-biblioteker.
◦ tpl – template-filer for jsRender skal ligge i denne mappen.
• Controllers – mappen med alle MVC-controllere.
• MVCUtil – hjelpefunksjoner og -klasser som er direkte knyttet til MVC-
rammeverket.
• ViewModels – her hviler view models; presentasjons-modellen til views
• Views – mappen inneholder undermapper for hver controller med view-filer.
Inneholder også mappen Shared med delte views som for eksempel _Layout.cshtml
som er view-filen alle andre views benytter som layout-fil68 (tilsvarende Master
Page69 i klassisk ASP.NET).
68 http://weblogs.asp.net/scottgu/archive/2010/10/22/asp-net-mvc-3-layouts.aspx 69 http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
49
Produktdokumentasjon
50
Prosessdokumentasjon
Prosessdokumentasjon
Innhold1 Innledning..........................................................................................................................................5
1.1 Om språket i rapporten..............................................................................................................5
1.2 Valget om å gjøre oppgaven individuelt....................................................................................5
2 Involverte parter................................................................................................................................7
2.1 Bedriften....................................................................................................................................7
2.2 Produktet....................................................................................................................................8
2.3 Studenten...................................................................................................................................9
2.4 Høgskolen..................................................................................................................................9
3 Planleggingsfasen............................................................................................................................10
3.1 Valg av oppgave.......................................................................................................................10
3.2 Analyse og rekognosering........................................................................................................10
3.2.1 Støtter Propell oppgaven?................................................................................................11
3.2.2 Utgangspunkt...................................................................................................................12
3.2.3 Navn.................................................................................................................................12
3.2.4 Lønnsomhet......................................................................................................................12
3.3 Mål og rammebetingelser........................................................................................................13
3.3.1 Oppgavetekst....................................................................................................................13
3.3.2 Tolking av oppgaven........................................................................................................13
3.3.3 Rammebetingelser............................................................................................................14
3.3.4 Ressurser..........................................................................................................................14
3.3.4.1 Budsjett.....................................................................................................................15
3.3.5 Kunnskap.........................................................................................................................15
4 Utviklingsmetodikk.........................................................................................................................16
4.1 Om individuelt arbeide............................................................................................................16
4.2 Smidig utviklingsmetodikk......................................................................................................16
4.2.1 En personlig, smidig utviklingsprosess............................................................................17
4.2.2 Personal eXtreme Programming (PXP)...........................................................................17
4.3 Testdrevet utvikling ................................................................................................................20
5 Valg av teknologier..........................................................................................................................21
ASP.NET MVC 3.............................................................................................................21
C#.....................................................................................................................................21
2
Prosessdokumentasjon
Løk-arkitektur..................................................................................................................22
Fluent NHibernate...........................................................................................................22
Ninject..............................................................................................................................23
jQuery .............................................................................................................................23
NUnit ..............................................................................................................................23
AutoMapper ....................................................................................................................23
SQLite .............................................................................................................................23
5.1 Verktøy.....................................................................................................................................24
Visual Studio....................................................................................................................24
Subversion.......................................................................................................................24
Google Chrome................................................................................................................25
Dropbox...........................................................................................................................25
OpenOffice......................................................................................................................25
Gimp................................................................................................................................26
6 Oppstartsfasen.................................................................................................................................26
6.1 Kravspesifikasjon.....................................................................................................................27
6.2 Brukerhistorier.........................................................................................................................27
6.2.1 Akseptansekriterier...........................................................................................................28
6.3 Prosjektplan.............................................................................................................................28
6.3.1 Iterasjonsvarighet.............................................................................................................29
6.3.2 Iterasjonsstart og rapportskriving.....................................................................................29
6.4 Risikoanalyse...........................................................................................................................30
6.5 Risikoevaluering .....................................................................................................................31
6.5.1 Arbeids-PC slutter å fungere/blir stjålet...........................................................................31
6.5.2 Tap av kritisk data............................................................................................................32
6.5.3 For lite tid.........................................................................................................................32
6.5.4 Misforståelser mellom student og oppdragsgiver............................................................32
6.6 Prosjektnettsted og -notatbok...................................................................................................32
7 Arbeidsfasen ...................................................................................................................................33
7.1 Iterasjonene..............................................................................................................................33
7.1.1 Start .................................................................................................................................33
7.1.2 Utførelse...........................................................................................................................33
3
Prosessdokumentasjon
7.1.3 Slutt og retrospektiv.........................................................................................................34
7.2 Arbeidstid og -miljø.................................................................................................................34
7.3 Kontakt med bedrift og sluttbrukere........................................................................................35
7.4 Møte med veileder...................................................................................................................35
7.5 Kodestandard...........................................................................................................................35
7.6 Prototyping...............................................................................................................................36
7.7 Testing......................................................................................................................................36
7.7.1 Manuell testing.................................................................................................................36
7.8 Debugging................................................................................................................................37
8 Avslutningsfasen..............................................................................................................................38
8.1 Dokumentering........................................................................................................................38
8.2 Unøstede tråder........................................................................................................................38
9 Post-mortem....................................................................................................................................38
4
Prosessdokumentasjon
1 InnledningDenne rapporten inneholder prosessdokumentasjon for arbeidet med hovedprosjektet
Propell ved Høgskolen i Oslo og Akershus (HiOA), våren 2012.
Propell er et kunderelasjonhåndteringsystem (CRM-system) utviklet av Biip.no AS og er i
bruk av flere bedrifter.
Oppgaven gikk ut på å forenkle videreutvikling og deployering av Propell. Oppdragsgiver
ønsket en arkitektur som gjorde det mulig å legge til nye funksjonalitet raskt og smertefritt.
Et delmål med oppgaven var også at allerede eksisterende funksjoner skulle kunne gjøres
om til moduler, slik at det er mulig å selge Propell i skreddersydde pakker; en mediebyrå-
bedrift har for eksempel nødvendigvis ikke behov for varelager-funksjonaliteten i Propell.
Det har vært et ubeskrivelig lærerikt prosjekt, og jeg føler at jeg har fått utnyttet mye av
kunnskapen jeg har tilegnet meg under studiet.
Jeg ønsker spesielt å takke daglig leder i Biip.no, Erling Løken Andersen, for å ha gitt meg
muligheten til tett samarbeid med bedriften og sluttbrukere.
1.1 Om språket i rapportenDet hersker liten tvil om at engelsk har vokst frem som Vestens lingua franca i tiden etter
annen verdenskrig. Informatikk er et ungt felt og på grunn av dette, samt på grunn av
USAs rolle i utviklingen av informatikk, er engelske terminologier like uunngåelig for en
informatikk-student som latinske uttrykk er for en juss- eller medisinstudent.
Jeg har forsøkt å benytte norske ord og utrykk hvor det er naturlig, men det ikke alltid de
norske ordene hundre prosent gjenspeiler de engelske; i flere tilfeller faller noe av
betydningen bort i oversettelsen.
1.2 Valget om å gjøre oppgaven individueltDet var flere faktorer som gjorde at jeg ønsket å gjøre prosjektet individuelt.
Jeg startet dataingeniør-studiet ved Høgskolen i Sør-Trønderlag og byttet så studiested til
Høgskolen i Oslo og Akershus da jeg flyttet til Oslo.
Da jeg først kom til HiOA ved andreåret følte jeg at det allerede var dannet «klikker» i
klassene. Det første semesteret hadde jeg også flere fag som var felles for flere linjer; jeg
5
Prosessdokumentasjon
syns derfor det var litt vanskelig å komme ordentlig i kontakt med medstudenter ved
studiet.
Enkelte av fagene jeg hadde krevde gruppearbeid, og jeg ble da plassert i det jeg vil kalle
«oppsamlingsgrupper». Jeg fikk svært dårlig erfaring med disse gruppene og har det
inntrykk av at dette ikke bare var uflaks.
Da tiden kom og grupper skulle dannes for hovedprosjekt kjente jeg bare noen få
medstudenter; alle hadde allerede dannet grupper. Jeg følte at hovedprosjektet var et
såpass viktig prosjekt at jeg ønsket svært lite at det skulle gjøres i en tilfeldig
oppsamlingsgruppe.
Dette var hovedårsaken til at jeg sendte en søknad om å få gjøre hovedprosjektet
individuelt, men det var også praktiske årsaker til dette knyttet til fysisk plass ved
bedriften; siden jeg jobbet individuelt hadde jeg plass blant utviklerne og sluttbrukerne ved
bedriften.
Forsiden av Propell
6
Prosessdokumentasjon
2 Involverte parter
2.1 BedriftenBiip.no AS er en webutviklings-bedrift som holder til i Oslo.
Bedriften ble startet i sammenheng med nettsiden biip.no1 i 2005. Siden vokste seg fort
opp til å bli Norges største sosiale nettverk for unge2. Biip.no AS ble kjøpt opp av Egmont
AS og TV2 AS.
Biip.no AS videre utvidet porteføljen med utvikling og drifting av en av Norges største
redaksjonelle nettsider for spill; spill.no3. Biip.no AS drifter også blogg-nettstedet
bloggr.no4, som er et av Norges største blogg-nettsted (over 15.000 registrerte bloggere).
Foruten nettsteder har bedriften utviklet flere web-løsninger, for eksempel CMS-systemet5
Butler som er i bruk på flere av Egmonts nettsteder.
Biip.no AS driver også med konsultasjonsarbeid.
2.2 ProduktetPropell er som nevnt et kunderelasjonhåndsystem; et system for å håndtere en bedrifts
interaksjoner med kunder, bedrifter og salg. Propell hjelper å automatisere og organisere
salgsaktiviteter samt å holde oversikt over alle kunder og bedrifter med tilhørende
kontaktpersoner.
Da Propell ble laget både av og for Biip.no AS er Propell spesielt utviklet for Internett-
aktører som ønsker å kapitalisere på sitt Internett-publikum.
Foruten Biip.no AS benyttes Propell av to andre bedrifter.
1 http://www.biip.no/ 2 http://annonse.biip.no/ 3 http://www.spill.no/default.aspx?section=articles&name=om 4 http://bloggr.no/ 5 http://en.wikipedia.org/wiki/Content_management_system
7
Prosessdokumentasjon
Kundeoversikten i Propell
2.3 StudentenProsjektet ble gjort individuelt av Øyvind Ingvaldsen (s161579).
2.4 HøgskolenDet er blitt avholdt ukentlige møter med prosjektveileder Larissa Sjarbani på HiOAs
lokaler, Holbergs plass.
8
Prosessdokumentasjon
3 Planleggingsfasen
3.1 Valg av oppgaveJeg (studenten) har vært deltidsansatt som juniorutvikler i Biip.no AS siden august 2011 og
i oktober 2011 foreslo daglig leder i Biip.no AS oppgaven til meg.
Jeg sendte søknad om å få gjøre prosjektet ved bedriften medio november 2011, og den ble
godkjent i desember 2011; med det premiss at alt arbeid med hovedprosjekt skulle foregå
utenfor arbeidstiden.
Avtalen med bedriften var at de tre arbeidsdagene skulle fortsette som normalt, mens de to
resterende dagene i arbeidsuken ble benyttet til ubetalt arbeid med hovedprosjektet.
Hovedfaktoren som fikk meg til å velge oppgaven var at jeg allerede jobbet i bedriften som
gav meg muligheten til direktekontakt med både sluttbruker og web-utviklere som kjente
Propell-løsningen.
En annen viktig faktor var det tekniske innholdet i oppgaven; jeg hadde fra før lite erfaring
med ASP.NET-plattformen så jeg anså oppgaven som en gylden mulighet til å sette meg
inn i en av de mest utbredte plattformene for web-utvikling.
3.2 Analyse og rekognoseringI skole- og hobbyprosjekter har jeg utelukkende startet med blanke ark. Siden Propell
allerede var et ferdigstilt produkt som bedriften hadde utviklet over flere år var
oppgaveformen derfor helt ny for meg.
Jeg døpte den første fasen til rekognoseringsfasen. Målet med denne fasen var å sette meg
inn i Propell; bli kjent med rammeverk, teknologi og kodestandard. Jeg la veldig stor vekt
på denne fasen, og mener det var et fornuftig valg siden jeg følte at jeg ikke kunne starte å
planlegge et plugin-system uten å kjenne Propell inn og ut.
Å sette seg inn i et fungerende system var helt nytt for meg og krevde relativt mye energi.
Ikke bare måtte jeg sette meg inn i relevante teknologier, men jeg måtte også til en viss
grad forstå hvordan de tidligere utviklerne hadde tenkt.
Jeg brukte store deler av januar bare til å sette meg inn i Propell-systemet.
Jeg mener at det å sette seg inn i ferdigstilte systemer kunne vært en del av dataingeniør-
utdannelsen. Man kunne for eksempel unyttet open source-prosjekter til dette.
9
Prosessdokumentasjon
Argumentet mitt her er at en stor del av systemutvikling er vedlikehold og ekstendering
av systemer. Det å sette seg inn i andres kildekode er en relativt generell kunnskap som
jeg mener fint kunne hatt plass i dataingeniør-utdanningen.
Da jeg hadde bygget opp en god forståelse av systemet og dets deler, begynte jeg å lese om
forskjellige plugin-arkitekturer for å finne en som ville fungere bra med Propells
arkitektur.
Under denne prosessen oppdaget jeg dog flere arkitekturelle «uheldigheter» med Propell-
systemet.
3.2.1 Støtter Propell oppgaven?Oppdragsgiver ønsket at nåværende funksjoner i Propell skulle kunne gjøres om til
moduler, samt at ny funksjonalitet skulle kunne legges til i form av moduler eller plugins-
Det uten at det krevde noen endringer av selve system-kjernen.
En forutsetning for å implementere et slikt system er at det ikke eksisterer mange sterke
avhengigheter6 (spesielt patologiske avhengigheter7) innad i systemet. Dette fantes det
dessverre mange eksempler på i Propell-systemet.
Utviklingen av Propell startet i 2004 og var direkte basert på koden bak biip.no.
Arkitekturen og teknologien som ble benyttet var på den tiden ansett som god, men den
har uten tvil begrensninger sett med dagens web-utviklings-øyne.
Et annet stort problem med Propell var at flere utviklere hadde jobbet med prosjektet
sekvensielt; mange individuelle standarder og tankemønster hadde blitt benyttet og det
skapte inkonsistens i systemet.
Et godt eksempel på dette er bruken av dataaksess-teknologi: det var benyttet direkte
SQL-queries, lagrede prosedyrer og NHibernate om en annen.
Enda et problem med Propell var mangelen på skille mellom presentasjon og logikk.
Presentasjonsfilene var veldig store og uoversiktlige og inneholdt både forretnings-logikk
og front-end-kode.
Å klassifisere programvarearkitektur som enten bra eller dårlig er i stor grad subjektivt og
6 http://en.wikipedia.org/wiki/Coupling_(computer_programming) 7 ISO/IEC/IEEE 24765
http://www.iso.org/iso/catalogue_detail.htm?csnumber=50518
10
Prosessdokumentasjon
standarden på god programvarearkitektur er flytende. Jeg mente fremdeles, med tanke på
oppgaven, at problemene jeg nevnte over var gode argumenter for å gi Propell en grundig
ansiktsløftning.
3.2.2 UtgangspunktSpørsmålet som da oppstod var hvorvidt man skulle rydde opp i det nåværende systemet
eller bygge opp et nytt system, parallelt med Propell.
En viktig faktor her var tidsbruk, og jeg mente at det å bygge opp Propell på nytt, men ved
å benytte systemet som mal, ville være det som tok minst tid. Å rydde opp i den nåværende
koden ville kreve nøysomt planlagt refaktorisering, som jeg tror ville tatt lengre tid enn å
bygge det opp på nytt.
Siden det nye systemet skulle ha samme funksjonalitet ville store deler av det nye systemet
kunne både direkte og indirekte kopiere Propells kode.
3.2.3 NavnFor å skille det gamle systemet (Propell) ble det av bedriften foreslått et nytt navn til det
nye systemet; Rotor.
Det vil videre i rapporten benyttes til å identifisere det nye systemet. Det gamle systemet
vil bli referert til som Propell.
At ordene er synonymer kan kanskje videre i rapporten være en kilde til misforståelse.
Jeg håper det er klart at det med Propell menes det gamle systemet, mens Rotor
refererer til det nye systemet som ble bygget i løpet av prosjektet.
3.2.4 LønnsomhetÅ bygge opp Propell på nytt, på en moderne plattform og en god arkitektur, ville drastisk
forenkle drifting og videreutvikling av systemet. Med dagens system kom det relativt ofte
frem bugs og andre anormaliteter som krevde mye tid, et problem som ville være enklere å
unngå med et nytt system som var grundigere testet.
Det ville også gjøre det mulig å distribuere systemet i en pakke med moduler, skreddersydd
for hver enkelt bedrift. Det ville gi bedre mulighet til markedsføring mot bestemte
bedrifter.
11
Prosessdokumentasjon
Dette mente jeg var kostnadsmotiverende argumenter for gjenoppbygningen av systemet.
Jeg satt de frem for bedriften som var enig med meg.
3.3 Mål og rammebetingelserMålet med oppgaven var originalt å konstruere et plugin-system til Propell, samt
modulisere eksisterende funksjoner i Propell.
Da det, under analyse-fasen, ble gjort et valg om å bygge et nytt system basert på Propell,
ble målet fastsatt til følgende:
3.3.1 Oppgavetekst«Målet med oppgaven er å lage et CRM-system, Rotor, med utgangspunkt i Propell. Det
nye systemet skal ha samme funksjonalitet som Propell, men ha en arkitektur som på en
bedre måte støtter videreutvikling.»
3.3.2 Tolking av oppgavenDet ligger noe uklarhet i hva som menes med «... en arkitektur som på en bedre måte
støtter videreutvikling.» og det kreves derfor litt forklaring.
Som nevnt var det flere punkter som gjorde at Propell dårlig støttet videreutvikling:
• Avhengigheter (spesielt patologiske)
• Manglende skille mellom presentasjon og logikk
• Inkonsistens
Med bedre arkitektur menes derfor en arkitektur som
• Ikke inneholder unødvendige patologiske avhengigheter
• Har er klart skille mellom presentasjon og logikk
• Er konsistent (veksler ikke mellom teknologier og kodestandarder)
Disse punktene var følgende hovedmålet med oppgaven.
12
Prosessdokumentasjon
3.3.3 RammebetingelserDet eneste definitive teknologiske krav oppdragsgiver hadde til applikasjonen var at den
skulle kunne kjøre på en av deres IIS-servere8, og således benytte seg av ASP.NET-
plattformen. Oppdragsgiver hadde videre ingen teknologiske krav. Jeg satte selv opp noen
flere rammebetingelser jeg mente var givende for produktet og prosjektet.
• Applikasjonen skulle utvikles som en web-applikasjon på ASP.NET-plattformen.
• Brukergrensesnittet skulle være høyst interaktivt og benytte seg av Ajax for
asynkron oppdatering av nettsidene.
• Kritiske deler av systemet skal testet med unit testing.
• Teknologiske rammeverk og biblioteker skal vurderes nøye og profesjonelt – valg av
disse skal tas med kunnskap og oppgavemålene som grunnlag.
3.3.4 RessurserDet er åpenbart at den mest verdifulle ressursen i et individuelt prosjekt er tid. Jeg satte
derfor tidlig opp en tidsplan som jeg ønsket å følge. Jeg satte også opp ukeplaner ved
inngangen av hver uke for å konkretisere tidsbruken så mye som mulig.
Mine ressurser for kunnskap var primært bøker og nettsider. Jeg kjøpte flere bøker om de
relevante teknologiene; der i blant Pro ASP.NET MVC 3 Framework9, Pro ASP.NET 3.5 in
C# 200810 og jQuery in Action11.
Av nettsteder var StackOverflow12 den mest besøkte og mest hjelpsomme siden.
StackOverflow er en spørsmål-og-svar-side for programmerere. Omtrent hver gang jeg
kom over et problem var det noen som hadde hatt stilt et spørsmål om tilsvarende
problem; og som oftest hadde andre folk gitt et svar med løsningen på problemet.
Jeg hadde også en god ressurs i dokumentasjoner for de enkelte teknologiene. Som for
8 http://en.wikipedia.org/wiki/Internet_Information_Services 9 http://www.amazon.com/Pro-ASP-NET-MVC-3-Framework/dp/1430234040/ref=sr_1_1?
s=books&ie=UTF8&qid=1337950811&sr=1-1 10 http://www.amazon.com/Pro-ASP-NET-3-5-2008-Silverlight/dp/1430215674/ref=sr_1_8?
s=books&ie=UTF8&qid=1337950900&sr=1-8 11 http://www.amazon.com/jQuery-Action-Second-Bear-Bibeault/dp/1935182323/ref=sr_1_4?
s=books&ie=UTF8&qid=1337950855&sr=1-4 12 http://stackoverflow.com/
13
Prosessdokumentasjon
eksempel MSDN13 og jQuery-dokumentasjonen14.
Ellers ført ofte Google-søk til artikler og blogg-poster av utviklere.
3.3.4.1 Budsjett
For de fleste studenter er penger en beskjeden ressurs, jeg var inget unntak. Selv om mye
informasjon er tilgjengelig gratis på nettet var det noen veldig gode kilder (primært bøker)
som kostet penger.
En del av verktøyene som ble benyttet under prosjektet kostet også «litt» penger; en lisens
for Visual Studio 2010 Ultimate koster $11.900 (ca. 72.000kr, og det uten mva).
Som informatikk-student hadde jeg heldigvis tilgang til Microsoft Dreamsparks. Her hadde
jeg lisenser og muligheten til å laste ned et flertall av Microsoft-produkter, inkludert
Windows-operativsystemet, Visual Studio og Office.
Jeg hadde også en lisens på Visual Studio via jobben. Jeg var ikke helt sikker på hvordan
Dreamspark-lisenser var med tanke på kommersielle produkter så jeg valgte å benytte
denne lisensen under prosjektet.
Jeg bestemte meg for å sette opp et budsjett på 5.000kr til prosjektet, og jeg ønsket først og
fremst å benytte dette til relevant litteratur.
3.3.5 KunnskapVed oppstart av prosjektet hadde jeg litt kunnskap om web-utvikling via Ruby on Rails og
PHP. Jeg kjente relativt godt til W3C-standarder15 som XML, HTML og CSS, og hadde
benyttet litt JavaScript/jQuery før. Jeg hadde også hatt fag om systemutvikling, databaser
og datasikkerhet som hjalp veldig.
Min kunnskap om Java hjalp veldig da jeg skulle lære meg C# da det er to veldig nært
beslektede språk.
13 http://msdn.microsoft.com/en-us/library/ms123401.aspx 14 http://docs.jquery.com/Main_Page 15 http://www.w3.org/standards/webdesign/
14
Prosessdokumentasjon
4 Utviklingsmetodikk
4.1 Om individuelt arbeideNår en jobber individuelt har en ikke den psykologiske motivasjonen en får via
gruppearbeid; om en skulle overtre en tidsfrist i et gruppearbeid vil det alltid være en fare
for negativ tilbakemelding eller i verste fall eksklusjon fra gruppen. Sosiale dyr som oss
mennesker jobber hele tiden, både bevisst og underbevisst, for gruppeakseptans og denne
basale driften er en av hovedgrunnene til at gruppearbeid fungerer så bra.
Når en jobber alene har man naturligvis ikke denne motivasjonen; og jeg mener at
mangelen av denne er farligere enn det faktum at man må gjøre mye mer arbeid når en
jobber individuelt.
Jeg satte tidlig opp tidsskjema og prøvde hardt å unngå prokrastinering. Det var noen
tidsfrister som glapp, men alt i alt fulgte jeg skjemaet nøye.
Jeg hadde et ukentlig møte med min veileder ved HiOA, og dette hjalp meg veldig å følge
tidsskjema. Selv om veileder gav meg full frihet og ikke stilte noen formelle krav, skapte
det et indre press fra meg til å ha noe å vise frem hver uke.
4.2 Smidig utviklingsmetodikkJeg var fra starten av helt klar over at jeg ønsket å benytte en smidig utviklingsmetodikk.
Siden jeg satt to dager i uken hos bedriften og hadde direkte kontakt med både bedriften
og sluttbrukere passet dette veldig bra med det utviklingsparadigmet.
Smidig systemutvikling har fokus på samspill mellom utvikler og kunde; samt foretrekker
intuitiv og fungerende programvare fremfor fyldig dokumentasjon. Smidig systemutvikling
ønsker også å reagere «smidigere» på endringer; dette åpner for et mye tettere og
responsivt samarbeid med kunden.
En kort vei mellom utvikler og kunde er uten tvil fordelaktig ved smidig systemutvikling og
siden jeg satt sammen med kunden to dager i uken kunne ikke veien vært mye kortere.
Dette åpnet for mange uformelle samtaler rundt krav og funksjonalitet og jeg følte at denne
åpne dialogen førte til at sluttproduktet ble i aller høyeste grad et resultat av samarbeid
mellom utvikler og kunde.
15
Prosessdokumentasjon
4.2.1 En personlig, smidig utviklingsprosessSiden jeg gjorde prosjektet individuelt måtte jeg finne en utviklingsrammeverk som tok
høyde for dette. Jeg hadde hatt faget systemutvikling på høgskolen som tok for seg ulike
metodikker, men alle var ment for arbeid i grupper.
Jeg hadde litt kunnskap om Personale Software Process16 (PSP), men ønsket å finne en
smidigere prosess.
De to rammeverkene innenfor smidig utvikling jeg kjente best til var scrum og extreme
programming (XP), så jeg satte ut på jakt etter versjoner av disse som var modifisert til
individuelt arbeide.
Jeg fant flere artikler som tok for seg dette, og der hadde de døpt de individualiserte
variantene for henholdsvis Personal Scrum og Personal Extreme Programming (PXP).
Jeg fant en god artikkel17 av tre forskere ved Universitetet i Sofia hvor de beskrev PXP. De
hadde både tatt utgangspunkt i XP og PSP.
Jeg syns det de beskrev i artikkelen virket som en fornuftig og strukturert prosess, så jeg
valgte å benytte denne.
4.2.2 Personal eXtreme Programming (PXP)PXP er en smidig systemutviklingsprosess for autonome (selvstyrte) utviklere. PXP baserer
seg på en lettere variant av PSP som blant annet har mindre krav til dokumentasjon under
prosessen. PXP baserer seg også på XP, modifisert til å passe for autonome utviklere.
PXP er følgelig en smidig ,og derav iterativ, utviklingsprosess.
PXP-prosessen baserer seg på følgende prinsipper:
• PXP krever at utvikleren har høy disiplin i forhold til å følge prosessen.
• Utvikleren bør måle, loggføre og analysere daglig arbeid.
• Utvikleren bør lære fra variasjon i egne prestasjoner.
• Prosjektet bør kontinuerlig testes
• Utvikler bør forsøke å automatisere arbeidsdagen mest mulig
16 http://en.wikipedia.org/wiki/Personal_software_process 17 https://research.uni-sofia.bg/bitstream/10506/647/1/S3T2009_37_YDzhurov_IKrasteva_SIlieva.pdf
16
Prosessdokumentasjon
Fasene i PXP er relativt lik andre smidige utviklingsprosesser.
Fasene i en PXP-prosess.
17
Prosessdokumentasjon
4.3 Testdrevet utvikling Jeg hadde lest og hørt mye bra om testdrevet utvikling og ønsket å utnytte dette i
prosjektet. Selv om jeg ikke benyttet dette fult ut over hele prosjektet, viste det seg å være
en veldig fornuftig måte å utvikle programvare på.
I kjernen av testdrevet utviklingen befinner det seg små testmetoder, kalt enhetstester. En
enhetstests oppgave er å teste en enhet av kildekoden etter gitte kriteria. En enhet av
kildekoden er et relativt begrep, men kan tolkes som den minste testbare delen av et
program. Dette kan være en metode, en hel klasse, eller kanskje i noen tilfeller en hel
modul.
I testdrevet utvikling lager man slike enhetstester før man i det hele tatt implementerer
delen av programmet som utfører det testen tester. Ved å skrive testen først har man fokus
på funksjonalitet fremfor implementasjon; dette gjør også at man er bedre rustet mot
endringer.
Siden testdrevet utvikling baserer seg på korte iterasjoner med rask tilbakemelding passer
det veldig bra med smidig utvikling.
En bonus ved testdrevet utvikling er at man via utviklingen automatisk har testdekning av
koden.
18
Prosessdokumentasjon
5 Valg av teknologierDet eneste kravet fra oppgavegiver var, som tidligere nevnt, at den ferdige applikasjonen
skulle kjøre på ASP.NET-plattformen. Bortsett fra det kunne jeg fritt velge rammeverk og
programmeringsspråk.
Jeg ønsket å gjøre nøye veide valg så jeg brukte bevisst mye av tiden etter analyse-fasen til
å sette meg inn i diverse rammeverk og teknologier. Her er teknologiene jeg valgte, samt en
liten kommentar om hvorfor og om alternativer.
Teknologiene er beskrevet dypere i produktrapporten.
ASP.NET MVC 3
Da jeg skulle holde meg til ASP.NET-plattformen hadde jeg primært to valg når det gjaldt
web-rammeverk: «klassisk» ASP.NET med en Code Behind-modell eller ASP.NET MVC
som baserer seg på MVC-mønsteret.
Ett av punktene jeg anså som et problem i Propell var mangelen på skille mellom
presentasjon og logikk, og dette var delvis fordi Propell var bygd på Code Behind-
modellen.
Jeg hadde litt erfaring med MVC i web-rammeverk fra Ruby on Rails, og visste hvor enkelt
det var å opprettholde skillet mellom presentasjon og logikk med MVC-mønsteret.
Jeg følte også at web-applikasjoner i MVC-mønsteret enklere beholdt en logisk struktur
som gjorde at MVC-prosjekter føltes (iallfall for meg) mer oversiktlig.
På bakgrunn av dette valgte jeg å få for Microsofts ASP.NET MVC-rammeverk. Da jeg
startet prosjektet var versjon 4 nettopp kommet ut i beta-form. Jeg valgte dog å benytte
den siste stabile versjonen; ASP.NET MVC 3.
Å konvertere fra MVC 3 til MVC 4 skal være en relativt enkel prosess i følge flere kilder
på nettet.
C#
Siden jeg skulle utviklet på ASP.NET måtte jeg naturligvis velge et av .NET-språkene. De to
mest utnyttede språkene er C# og Visual Basic. Jeg hadde ingen direkte erfaring med noen
av dem, men kjente godt til nært beslektede språk.
Et tredje valg som jeg vurderte sterkt var F#. F# er et programmeringsspråk som støtter
19
Prosessdokumentasjon
flere paradigmer, men som har sine røtter i funksjonelle språk (ML og OCaml). Fra og med
Visual Studio 2010 har F# endelig fått status som et fullverdig medlem av .NET-familien;
det vil blant annet si at F# har tilgang til alle .NET-biblioteker, inkludert ASP.NET.
F# er dessverre ikke helt integrert med ASP.NET i Visual Studio – det finnes enda ikke
prosjektmaler for F#-prosjekter i ASP.NET. Det kreves derfor litt fikling, noe jeg helst
ønsket å unngå.
Det som til slutt fikk meg til å velge C# var tre ting:
• Propell var skrevet i C# - det vil være enklere å resirkulere kode fra Propell
• Jeg hadde ganske god kjennskap til Java, som jeg visste delte mye av syntaksen til
C#.
• Utviklerne i bedriften hadde kjennskap til flere språk, men benyttet C# mest; det
var derfor enklest for dem om Rotor var skrevet i C#
Løk-arkitektur
Jeg ønsket å benytte en programvarearkitektur for Rotor som bedre tok høyde for målet
med oppgaven enn Propells nåværende arkitektur. Jeg ble tipset om løk-arkitekturen via
en artikkel18 av Jeffrey Palermo, og den virket som en veldig fornuftig arkitektur for større
programvareprosjekter.
Ett av løk-arkitekturens hovedmål var å løse opp de unødvendige avhengigheter som man
ofte finner i prosjekter. Et annet var å løsrive systemet fra dataaksess-teknologi og generelt
gjøre systemet mindre data-sentrisk.
På bakgrunn av dette valgte jeg å benytte løk-arkitektur for Propell.
Fluent NHibernate
NHibernate er basert på Hibernate som er et modent og populært ORM-rammeverk. Jeg
valgte derfor å benytte NHibernate fremfor for eksempel Entity Framework, som er relativt
nytt.
Jeg valgte å benytte Fluent NHibernate fordi det gjør det enklere å mappe (eventuelt
refaktorisere mapping av) domene-entitetene. NHibernate utfører tradisjonelt mapping
ved hjelp av XML-filer som definerer mappingene, mens Fluent NHibernate mapper
18 http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
20
Prosessdokumentasjon
klassene i strongly typed C#-kode.
Ninject
For Inversion of Control (IoC) valgte jeg Depdency Injection-rammeverket Ninject. IoC var
helt nytt for meg så jeg de eneste kravene jeg hadde var at rammeverket var enkelt å bruke
og fungerte. Ninject dekker disse kravene i aller høyeste grad, og er i tillegg det mest
populære IoC-rammeverket til .NET.
jQuery
Jeg valgte jQuery fordi det er enkelt og veldig populært; om jeg hadde behov for
funksjonalitet som ikke fantes i kjernen av jQuery var det relativt stor sjanse for at noen
andre hadde laget en plugin som tilbød funksjonaliteten.
Propell hadde også benyttet jQuery, som gjorde valget enda enklere.
NUnit
Til unit testing valgte jeg rammeverket NUnit. Dette er et test-rammeverk som deler
grensesnitt med mange andre rammeverk (som originalt er basert på SUnit). Fordelen med
dette var at jeg hadde muligheten til å lære et test-rammeverk som jeg senere kunne
benytte på andre plattformer.
En annen faktor som spilte inn var at Visual Studios innebygde test-rammeverk ikke
støttet mocks19. Selv om jeg kunne benyttet det veldig populære mocking-rammeverket
Moq20 ønsket jeg hele tiden å holde antall eksterne referanser lavt.
AutoMapper
Jeg valgte AutoMapper ganske raskt da jeg oppdaget at jeg hadde behov for å mappe
mellom objekter. AutoMapper er populært, lite, og skreddersydd for én ting: mappe
mellom objekter.
SQLite
Helt i startfasen av prosjektet fikk jeg en innføring i deployering av Propell. Jeg opplevde
da personlig hvor krunglete oppsett av database kunne være. Selve oppsettet av nettsidene
med tilhørende back-end var bare snakk om å flytte relevante filer over til web-serveren,
19 http://en.wikipedia.org/wiki/Mock_object 20 http://code.google.com/p/moq/
21
Prosessdokumentasjon
men oppsettet av database krevde dessverre en del arbeid og var uten tvil en kilde til feil.
Jeg ønsket å gjøre deployering av Rotor smertefritt og ønsket derfor å vurdere et alternativ
til en dedikert relasjonsdatabase-applikasjon på en ekstern server som krevde oppsett med
masse konfigurasjon.
Jeg hadde hørt mye bra om SQLite21 og undersøkte eventuelle negative sider ved det. Den
eneste store negative tingen med SQLite var at skriving til databasen var sekvensiell; når
det skrives til databasen blir databasefilen låst for skriving til operasjonen er over.
I en applikasjon som Rotor, ville det dog ikke være et merkbart problem. Dette er først et
problem i applikasjoner som har store mengder skrivinger til databasen per sekund, noe
Propell ikke skulle gjøre.
5.1 Verktøy
Visual Studio
For utdanning på .NET-plattformen har man få valg når det kommer til valg av IDE22, men
til gjengjeld oppfordres man til å benytte det kanskje mest solide IDE-et som er tilgjengelig
per i dag; Visual Studio.
Man kan få en gratis lisens til Express-versjonen, men den mangler en del kritiske
funksjoner (som for eksempel å ha flere prosjekter i en solution).
Jeg benyttet derfor en lisens til Ultimate-versjonen jeg hadde fått via jobben.
Subversion
Jeg valgte å bruke Subversion til versjonskontroll på grunn av to ting:
• Jeg hadde tilgang til en private subversion-server.
• Subversion kan integreres i Visual Studio (ved hjelp av AnkhSVN23).
21 http://www.sqlite.org/ 22 http://en.wikipedia.org/wiki/Integrated_development_environment 23 http://ankhsvn.open.collab.net/
22
Prosessdokumentasjon
Google Chrome
Jeg har privat hatt Google Chrome som førstevalg til nettleser siden den ble sluppet så det
var sånn sett ikke noe overraskende valg her.
Årsaken til at jeg velger å klassifisere Google Chrome som et verktøy i prosjektet er fordi
Google Chrome har veldig gode debugging-muligheter innebygd; jeg benyttet ikke bare
Google Chrome for å se på nettsidene.
Via utviklerverktøy-vinduet kunne jeg enkelt se feilmeldinger i JavaScript-kode, inspisere
DOM-elementer, se innhold i HTTP-requester/-responser, se cookies og mye mer.
Dropbox
Jeg valgte Dropbox til lagring av dokumenter da jeg hadde benyttet Dropbox privat i flere
år.
OpenOffice
Jeg er svært positiv til åpen kildekode og mener at alle burde ha gratis tilgang på et så
essensielt verktøy som et tekstredigeringsprogram; jeg ønsket derfor å benytte et
tekstredigeringsprogram med åpen kildekode for skriving av prosjektdokumenter. Før
2010 var valget enkelt: OpenOffice.
OpenOffice er en open source office-suite, utviklet for å være mest mulig kompatibel med
Microsoft Office. OpenOffice er utviklet i Java av Sun Microsystems.
I september 2010 kjøpte Oracle opp Sun Microsystems, en avgjørelse som ikke var populær
i open source-miljøet. Oracle hadde tidligere det året kjøpt og lukket kildekoden til
OpenSolaris, et UNIX-basert operativsystem utviklet av Sun Microsystems, og mange
fryktet at Oracle ville gjøre det samme med OpenOffice.
Etter oppkjøpet skjedde det derfor en reaksjon i miljøet i form av en forgrening av
OpenOffice kalt LibreOffice24; denne forgreningen skulle styres av en ny organisasjon kalt
The Document Foundation hvis oppgave var å promotere open source-programvare.
Oracle kunngjorde senere (i april 2011) at de ikke lengre skulle støtte den kommersielle
utviklingen av OpenOffice, og sa opp de fleste av de betalte utviklerne som jobbet på
OpenOffice. Flere av disse sluttet seg til utviklingen av LibreOffice.
24 http://en.wikipedia.org/wiki/LibreOffice
23
Prosessdokumentasjon
Like etter dette kunngjorde Oracle at de skulle gi ansvaret og kildekoden til OpenOffice til
Apache Software Foundation25.
Med denne fryktelig krunglete historien de siste to årene, er det litt vanskelig å bestemme
seg for hvilket av prosjektene man burde støtte. Begge prosjektene ser ut til å holde seg
open source i nærmeste fremtid iallfall.
Jeg benyttet først LibreOffice på min private maskin, men da den kræsjet og jeg byttet til
en jobb-PC byttet jeg også til OpenOffice; kort og godt fordi det allerede var installert på
maskinen.
Begge suitene fungerer perfekt for mitt bruk, men jeg kommer nok til å støtte opp om
LibreOffice i fremtiden.
Gimp
Siden den grafiske designeren ved bedriften senere skulle style siden var det ikke så mange
ganger jeg måtte ty til bilderedigering. De gangene det skjedde benyttet jeg open source-
programvaren Gimp.
Til de enkleste tingene, for eksempel kutting av screenshots o.l., benyttet jeg like så godt
MS Paint. Enkelt og greit.
25 http://en.wikipedia.org/wiki/Apache_Software_Foundation
24
Prosessdokumentasjon
6 OppstartsfasenDa jeg hadde tatt endelige valg av teknologi begynte jeg å sette meg inn de ulike
teknologiene. Jeg hadde da allerede en overfladisk forståelse av teknologiene fordi jeg
hadde satt meg litt inn i dem da jeg skulle foreta valg av teknologier.
Det tok derfor ikke for lang tid (litt over to uker) før jeg følte meg klar til å ta fatt på
utviklingen.
6.1 KravspesifikasjonFør jeg startet med utviklingen satt jeg opp en kravspesifikasjon for systemet. Denne
spesifikasjonen anså jeg dog ikke som skrevet i stein, og dette var i tråd med
utviklingsmetodikken jeg hadde valgt.
Kravspesifikasjonen er delt opp i funksjonelle og ikke-funksjonelle krav. De funksjonelle
kravene er en presis beskrivelse av en funksjonalitet i systemet, mens ikke-funksjonelle
krav er mer generelle krav som ofte kan være litt vage.
Jeg hadde en litt spesiell situasjon da alle de funksjonelle kravene allerede var definert i
form av et allerede fungerende system; min oppgave var derfor først og fremst å
identifisere de funksjonelle kravene.
De ikke-funksjonelle kravene formulerte jeg i samarbeid med oppdragsgiver.
Kravspesifikasjon kan leses i sin helet i vedlegg 1.
6.2 BrukerhistorierEn brukerhistorie er en kort beskrivelse av en sluttbrukers handling og resultat basert på
brukerens rolle. Disse er basert på de funksjonelle kravene til systemet, og formuleres ofte
slik:
«Som en [brukerrolle], vil jeg [handling] slik at [resultat]»
Et eksempel på en brukerhistorie kan da være:
«Som en selger, vil jeg kunne slette ett av mine egne salg, slik at det fjernes fra systemet»
Resultatet kan ofte være unødvendig eller implisert i handlingen, brukerhistorien kan da
ha formen:
«Som en [brukerrolle], vil jeg [handling]»
25
Prosessdokumentasjon
Brukerhistorier står ofte veldig sentralt i smidig utvikling og brukes ofte som basis for
iterasjoner. Det er også populært å definere meta-informasjon til brukerhistorier, som for
eksempel kompleksitet, viktighet og en tekst som forklarer hvordan brukerhistorien kan
demonstreres (for å sjekke om historien er implementert).
I tråd med (P)XP ønsket jeg å holde dokumentasjonen lett, så jeg valgte å ikke skrive en
demonstrasjons-tekst til hver brukerhistorie. Dette burde det være forståelig ut fra selve
brukerhistorien om den er presis og godt skrevet.
Jeg benyttet en skala fra 0 til 10 for å beskrive kompleksitet og viktighet, hvor 0 er minst
(ingen) og 10 er høyest.
6.2.1 AkseptansekriterierDet er vanlig å definere en eller flere akseptansekriterier for hver brukerhistorie. Jeg valgte
å ikke gjøre dette, med samme argument som ved demonstrasjons-tekster for
brukerhistorier; i en smidig prosess skal de funksjonelle kravene kunne endres under
utviklingen, og det er viktig at man reagerer smidig på dette.
Siden akseptansekriteria er avhengige av brukerhistoriene som igjen er avhengige av
kravspesifikasjon, ville en endring i et funksjonelt krav i verste fall kreve omskriving av en
eller flere akseptansekriterier.
Siden jeg var én person som jobbet på prosjektet ønsket jeg ikke å benytte mer tid på
prosjektdokumentasjon enn nødvendig, noe som var i tråd med PXP-prosessen jeg hadde
valgt å benytte.
Jeg valgte derfor å ikke skrive akseptansekriterier til brukerhistoriene.
6.3 ProsjektplanSiden jeg jobbet individuelt anså jeg det som svært kritisk at en plan ble fulgt; det gikk ikke
ut over noen andre enn meg selv om jeg ikke overholdt frister.
Jeg hadde fått tips om Microsoft Project26 fra en av utviklerne ved bedriften. Jeg hadde i
utgangspunktet ikke tenkt å benytte noe spesiell programvare for dette, og hadde videre
ikke satt av noen penger i budsjettet til dette.
26 http://www.microsoft.com/project/en-us/project-management.aspx
26
Prosessdokumentasjon
Jeg hadde som student tilgang til Microsoft Dreamsparks27 hvor jeg heldigvis hadde en
studentlisens og muligheten til å laste ned Microsoft Project, jeg valgte derfor å benytte
Microsoft Project for å planlegge prosjektet.
6.3.1 IterasjonsvarighetDet første valget jeg tok i forhold til prosjektplan var lengden av en iterasjon. I XP-
tradisjonen gjennomfører man ofte først én stor iterasjon hvor man implementerer
hoveddelene av prosjektet. De følgende iterasjonene gjennomføres så på vanlig, smidig vis.
Jeg valgte derfor å sette av 4 uker til den første og største iterasjonen og videre benytte 1
uke per iterasjon.
6.3.2 Iterasjonsstart og rapportskrivingJeg visste jeg kom til å benytte en del tid i analyse- og planleggingsfasene. Jeg valgte derfor
å gi meg litt god tid før jeg startet den første iterasjonsfasen. Jeg satte av over en måned i
starten til disse fasene og satte startdato for første iterasjon til mandag 13. februar.
Den første iterasjonen varte helt til søndag 4. mars, videre fulgte 9 iterasjoner à 1 uke.
Jeg satte av litt over to uker i slutten av prosjektet til rapportskriving. Siden jeg var alene
fryktet jeg at det kom til å bli dårlig tid til rapportskriving så selv om jeg prøvde å skrive litt
og litt i løpet av prosjektet, ønsket jeg å ha disse ukene som buffer.
Gantt-diagram av prosjektplanen. Tatt fra Microsoft Project.
27 https://www.dreamspark.com/
27
Prosessdokumentasjon
Et viktig prinsipp i smidig utvikling er at hver iterasjon er en fungerende versjon av
systemet. Jeg valgte derfor å ikke sette opp noen plan for milepæler/delutgivelser; jeg følte
at iterasjonene i seg selv fungerte som milepæler.
Jeg hadde også så tett kontakt med oppdragsgiver at jeg kunne vise frem prosjektet etter
og under iterasjonene.
6.4 RisikoanalyseOrdet risiko benyttes nokså løst i dagligtale. Det mange mener når de benytter ordet risiko
er sannsynligheten for at en hendelse inntreffer. Risiko er dog formelt definert som
produktet av sannsynligheten for at en hendelse inntreffer og konsekvensene av hendelsen.
En risikoanalyses hensikt er å identifisere risikoer slik at man har et godt grunnlag for en
risikoevaluering.
I risikoanalyser er det vanlig å benytte en skala fra 0-10 for sannsynlighet og konsekvens,
hvor 0 er minst (ingen) og 10 er høyest. Jeg har valgt å følge denne tradisjonen. Her følger
risikovurderingen jeg foretok ved prosjektstart:
Id Hendelse Sannsynlighet Konsekvens Risiko
1 Arbeids-PC slutter å fungere/blir stjålet 4 9 36
2 Tap av kritisk data (rapport-dokumentene, kildekode)
4 9 36
3 For lite tid/for ambisiøs prosjektplan 4 7 28
4 Sykdom 1 6 6
5 Misforståelser mellom student og oppdragsgiver
4 6 24
6 Teknologiske problemer/vanskeligheter ved innlæring
3 5 15
7 Annet skolearbeid krever for mye tid/energi
1 4 4
28
Prosessdokumentasjon
6.5 Risikoevaluering Risikoevaluering foretas med risikoanalysen som grunnlag. Man tar da for seg de
hendelser med høy risiko og irettesetter eventuelle risikoreduserende tiltak.
Hva som er godkjent som en høy risiko er relativt og det må her derfor benyttes skjønn.
Jeg valgte å anse risikoer på eller over 20 som høye. Jeg innførte følgende tiltak for å
redusere risiko for hendelsene med originalt høy risiko:
6.5.1 Arbeids-PC slutter å fungere/blir stjåletJeg benyttet min personlige laptop til arbeid med prosjektet. Laptopen var relativt ny
(under 6 måneder), men fordi jeg ofte reiste med den (til jobb og skole) vurderte jeg
sannsynligheten for havari/tyveri som relativt høy.
Jeg hadde også en liten hvit terrier i leiligheten som hadde en veldig løs definisjon av
«tyggeleke».
Tiltaket som ble innført var en avtale med oppdragsgiver om muligheten til lån av laptop
om min skulle ta kvelden.
Dette ble dessverre et eksempel på en hendelse som faktisk inntraff. En rolig vinterkveld
da jeg satt og jobbet på PC-en tok maskinen bokstavelig talt fyr; det kom røyk og
flammer ut av inntaket til strømladeren på siden av laptopen og tuppen av
strømledningen ble smeltet fast i dataen.
Takket være det risikoreduserende tiltaket jeg hadde ordnet på forhånd var jeg heldigvis
operativ igjen i løpet av kort tid!
6.5.2 Tap av kritisk dataSom informatikk-student har jeg alltid denne risikoen i bakhodet. Jeg hadde derfor,
allerede før prosjektstart, bestemt at jeg skulle benytte Dropbox til lagring av alle
prosjektrelaterte dokumenter.
Da jeg også skulle ha all kode under versjonskontroll, hadde jeg lagret all kritisk data
knyttet til prosjektet på eksterne servere.
Sjansen for at de eksterne serverne skulle havarere anså jeg som veldig lav.
29
Prosessdokumentasjon
6.5.3 For lite tidVi (student og oppdragsgiver) bestemte at jeg skulle kunne fortsette videreutvikling av
prosjektet etter at det var levert til sensur.
Det risikoreduserende tiltaket knyttet til for liten tid ble da å redusere eller forenkle
funksjonalitet, og heller implementere eventuelt manglende funksjonalitet på et senere
tidspunkt.
6.5.4 Misforståelser mellom student og oppdragsgiverMisforståelser kan føre til merarbeid som igjen fører til tap av tid. For å forsikre oss at vi
(student og oppdragsgiver) var samstemte hadde vi kontinuerlig kontakt under hele
prosjektet.
Siden jeg to dager i uken jobbet med prosjektet på oppdragsgivers lokasjon, hadde jeg
muligheten til små og uformelle korrespondanser med oppdragsgiver. Dette gjorde at
misforståelse fort ble oppdaget, og følgende ikke hadde stor konsekvens.
6.6 Prosjektnettsted og -notatbokJeg satte opp en side som jeg originalt ønsket å benytte til dokumentasjon. Jeg merket dog
senere at det var mye mer effektivt for meg å benytte en fysisk notatbok, så jeg valgte å
fokusere på å dokumentere daglige aktiviteter i notatboken. Jeg hadde tre notatbøker
knyttet til prosjektet; en til møtereferater, en til ukeplaner og en dagbok. Innholdet i disse
vil jeg gå nærmere inn på i seksjonen om de ukentlige møtene med veileder under
beskrivelsen av arbeidsfasen.
30
Prosessdokumentasjon
7 Arbeidsfasen Den første iterasjonsfasen var som tidligere omtalt på hele 4 uker. Dette fordi det i XP er
vanlig å utføre en noe større iterasjon først. Målet med den er å få på plass prosjektstruktur
og hovedfunksjonene i systemet.
7.1 Iterasjonene
7.1.1 Start Ved start av iterasjon (hver mandag) valgte jeg ut hvilke brukerhistorier som skulle
implementeres. I starten var jeg veldig usikker på hvor mange brukerhistorier jeg klarte å
implementere per iterasjon, jeg visste ikke helt hvordan jeg skulle anslå hvor lang tid en
brukerhistories implementasjon krevde.
Jeg følte at jeg fikk mye bedre forståelse for arbeidsmengden knyttet til hver brukerhistorie
utover i prosjektet.
7.1.2 UtførelseImplementasjon av brukerhistorier skulle i teorien bestå av tre deler
• Oppsett av unit-tester
• Koding
• Refaktorisering
Jeg fikk dog litt dårlig tid til dette i starten så først litt ute i prosjektet følte jeg at jeg fikk
pusterom til å lære meg, samt benytte, TDD. Så i de første iterasjonene fulgte
implementasjonene følgende velkjente mønster:
• Koding
Jeg ønsket å forbedre meg som autonom utvikler så det at jeg ikke følte jeg hadde tid og
overskudd til å i større grad benytte TDD var en liten skuffelse. Jeg fikk dog brukt det litt i
senere iterasjoner og føler jeg har forstått gangen og fordelene ved metodikken. Jeg
kommer uten tvil til å benytte det senere i arbeidslivet hvor det er mulighet til det.
31
Prosessdokumentasjon
7.1.3 Slutt og retrospektivEn iterasjon regnet jeg som fullført når alle utvalgte brukerhistorier var implementert. Som
sagt så var det vanskelig å beregne arbeidsmengden knyttet til brukerhistorier, jeg måtte
derfor foreta et par skippertak i starten for å holde iterasjons-tidsfristene.
Etter hver dag i iterasjonsfasen skrev jeg også en kort og presis beskrivelse av hva jeg
hadde gjort. Denne dagboken inneholdt for det meste korte setninger og stikkord, men var
til veldig mye hjelp da jeg skulle skrive prosjektrapporten.
Stikkordene var ofte nok til å huske tilbake og få den «Aha! Dét var det jeg gjorde den
dagen»-følelsen.
7.2 Arbeidstid og -miljøJeg prøvde å jobbe med hovedprosjektet mest mulig på dagtid og på hverdager. Det var
dog dager og helger hvor jeg satt sent oppe og leste/kodet. Jeg følte fremdeles ikke at det
var noe stort problem; en av mine favoritt-hobbyer er logisk nok å drive med
systemutvikling så det å måtte benytte fritid til dette gjorde meg i grunn ingenting.
Jeg brukte laptop, men hadde et «kontor» hjemme hvor jeg koblet den opp mot skjerm,
tastatur, etc. Jeg hadde samme oppsett hos oppdragsgiver. Jeg prøvde å benytte kontoret
mitt hver gang jeg jobbet med hovedprosjektet, og således skille det fra sofa- eller
sengesurfing.
Når man er in the zone er det litt vanskelig å legge kodingen vekk og resulterer ofte for meg
at jeg kan ligge til langt ut på natt å programmere på sengen. I forhold til hovedprosjektet
anså jeg dette som en dårlig vane, og prøvde å holde meg unna dette.
For meg fungerer overtrøtthet som alkohol; jeg føler at jeg gjør ting perfekt og tror jeg
har full kontroll, men oppdager dagen etter at jeg var flere kilometer ute på jordet.
7.3 Kontakt med bedrift og sluttbrukereJeg har hatt kontinuerlig kontakt med oppdragsgiver gjennom hele prosjektet. Jeg har
også hatt muligheten til direkte kontakt med sluttbrukere. Jeg har derfor hele tiden hatt
muligheten til å vise frem applikasjonen til oppdragsgiver og fått tilbakemeldinger.
32
Prosessdokumentasjon
7.4 Møte med veilederMin veileder ved HiOA var Larissa Sjarbani. I starten av prosjektet foreslo hun å avholde
ukentlige prosjektmøter, noe som jeg vurderte som en veldig bra idé med tanke på at jeg
jobbet alene og ellers ikke hadde noe ytre press på meg.
Veileder satt opp tre punkter som hun ønsket skulle tas opp på hvert møte:
• Referat fra forrige møte
• Dagbok over hva som er gjort den siste uken
• Ukeplan for kommende uke
Disse punktene krevde altså at jeg førte referater fra møter, dagbok over daglige aktiviteter
og skrev ned ukeplanene; krav som harmoniserte veldig bra med XP-metodikkens krav til
dokumentasjon.
Veileder stilte ingen krav til innhold i disse, ei heller at de faktisk ble skrevet; hun var
veldig klar på at dette kun var for å hjelpe studentene å følge tidsplanen.
Selv om det ikke var stilt noen formelle krav hjalp disse ukentlige møtene meg veldig å
følge tidsplanen; det å skulle møte opp tomhendt til det ukentlige møtet måtte føles litt
flaut.
En autoritær person og noen bortimot frivillige krav til dokumentasjon var iallfall det som
skulle til for meg for å skape et (imaginært) ytre press som hjalp meg til å overholde
tidsfrister.
7.5 KodestandardSelv om jeg utviklet alene måtte jeg ta høyde for at andre utviklere senere skulle enkelt lese
og forstå koden min. Jeg fulgte derfor de facto standard for C#-kode. Dette innebar for
eksempel:
• Beskrivende metodenavn og stor førstebokstav i metoder.
• Benytte camel case28 for metode-, klasse- og variabelnavn.
• Benytte Allman-stil29 for parenteser.
28 http://en.wikipedia.org/wiki/CamelCase 29 http://en.wikipedia.org/wiki/Indent_style#Allman_style
33
Prosessdokumentasjon
• Ikke skrive korte if-setninger på én linje.
Jeg benyttet også de facto standard for HTML/CSS/JavaScript. Navn på klasser og id-er
var for eksempel skrevet med bindestrek og liten forbokstav.
Én ting som skiller seg fra standarden er hvordan stilene er definerte på én linje. Jeg gjorde
dette i starten for å ha full oversikt over CSS-filen.
En ting jeg innså i ettertid var at jeg har vært altfor dårlig til å kommentere koden. Selv om
jeg har prøvd å skrive enkel og selvforklarende kode (for eksempel prøvd å holde metoder
så små og spesialiserte som mulig), er det uten tviler deler av prosjektet som for andre ville
vært lettere å forstå med en liten forklaring.
7.6 PrototypingJeg hadde ikke behov for å foreta en prototyping av brukergrensesnittet da Rotor skulle
være så likt Propell som mulig. Jeg kunne tegnet ned skisser av Propell, men jeg syns ikke
det var nødvendig når jeg bare kunne navigere til en av Propell-instansene og se hele
grensesnittet «live».
7.7 TestingSom tidligere nevnt ønsket jeg å benytte TDD. Om jeg hadde benyttet TDD i større grad
ville jeg optimalt hatt enhets-tester for hele systemet og enkelt kunne kjørt en global test av
hele systemet.
Jeg benyttet dessverre ikke TDD så mye som jeg ønsket, og måtte derfor i ettertid skrive
tester.
7.7.1 Manuell testingDen manuelle testingen av systemet gikk ut på å utføre brukerhistorier og se om resultatet
ble ønskelig, og at det ikke fulgte med noen negative side-effekter.
Dette innebar kort og godt å logge inn som den gitte rollen, utføre den beskrevne
hendelsen (om mulig), og observere resultatet.
7.8 DebuggingJeg visste litt om debugging da prosjektet startet, men hadde ingen direkte erfaring med
34
Prosessdokumentasjon
bruk av debuggere. Dette viste seg dog fort å være redningen ufattelig mange ganger når
systemet ikke fungerte som forventet. De integrerte debugging-mulighetene i Visual Studio
er virkelig glimrende.
Debuggeren stoppet ved et break point. Foruten verdifull informasjon i Call Stack kan jeg
se data-verdiene til variabler i scopet. Takket være integrasjonen med Visual Studio kan
jeg holde over variabler i kildekoden og se verdien (om de er definert).
Debuggeren ble utover i prosjektet det første jeg tydde til om ting ikke fungerte som
forventet.
35
Prosessdokumentasjon
8 Avslutningsfasen
8.1 DokumenteringJeg hadde som nevnt satt av litt ekstra tid i til dokumentering i enden av prosjektet. Jeg
hadde da allerede fått opp strukturen for prosess- og produktrapport, men jeg hadde en
god del seksjoner som måtte utfylles.
Ut fra min opplevelse med prosjektet var dokumentering det området jeg mest merket at
jeg jobbet individuelt, og det ble dessverre litt knapt med tid til dette. Jeg hadde uten tvil
ønske om å en mer fyldigere dokumentasjon av produktet og rapporten, men i lys av jeg
jobbet alene er jeg relativt fornøyd med resultatet.
8.2 Unøstede tråderDa jeg avsluttet den siste iterasjon-fasen hadde jeg et rimelig godt fungerende system, men
det var fremdeles funksjoner i Propell som ikke var implementert i Rotor.
Oppdragsgiver var fornøyd med Rotor og jeg kommer etter prosjektslutt til å fortsette
utviklingen av Rotor hos bedriften.
9 Post-mortemDet har vært et veldig interessant prosjekt; jeg kan uten tvil si at jeg aldri har hatt et så
lærerikt halvår før.
Jeg har fått muligheten til å benytte mye av kunnskapen jeg har fått via dataingeniør-
studiet og jeg har fått mulighet til å lære meg mange nye teknologier grundig.
Jeg har også fått erfaring med å lese andres kildekode og det å sette seg inn i fungerende
systemer. Dette er erfaring jeg er veldig glad for at jeg får ta med meg videre ut i
arbeidslivet.
De tingene jeg ikke her helt fornøyd med er først og fremst prosjektrapporten, som jeg
skulle ønske var litt mer fyldig. Det var også noen funksjoner som jeg trodde jeg skulle få
lagt til i systemet, men hvor tiden ikke strakk til.
36
Vedlegg 1 – Kravspesifikasjon
Funksjonelle krav
Autentisering
For å få tilgang til systemet må brukeren autentiseres ved hjelp av e-post og passord.
Administratorer, og kun administratorer, har muligheten til å legge til nye brukere og
slette brukere fra systemet.
Autorisering
Brukeres tilgang til deler av systemet må autoriseres basert på brukerens rolle, samt hvem
som har laget innholdet brukeren ønsker å få tilgang til. En bruker skal for eksempel kunne
slette et salg han selv har opprettet, men ikke salg som andre har opprettet med mindre
han er administrator for salg-modulen.
Salgoversikt
Systemet skal holde oversikt over alle salg, med tilhørende informasjon om status (utkast,
salg, tilbud, avslått, kreditert), selger, kunder, mediebyrå, salgselementer, pris, start- og
sluttdato.
Kundeoversikt
Systemet skal holde oversikt over alle kunder, med kontaktinformasjon, informasjon om
bransje, og eventuell tilknytning til mediebyrå. For kunder skal det også lagres relasjoner
med selgere; for hvert prosjekt kan en selger eie relasjonen til den gitte kunden.
Byråoversikt
Systemet skal holde oversikt over alle mediebyråer, med kontaktinformasjon.
Brukeroversikt
Systemet skal holde oversikt over brukerne av systemet. Hver bruker har et navn, en unik
e-post-adresse, et passord som skal lagres som en hash, og et eventuelt profilbilde. Brukere
skal være knyttet til en brukerrolle.
Brukerroller
En brukerrolle er en navngitt beskrivelse av rettigheter til ulike deler av systemet. For hver
del av systemet skal det bestemmes et brukernivå (Gjest, Bruker, Moderator,
Administrator), og dette nivået benyttes ved autorisering.
Målet med brukerrolle fremfor å bare bruke et globalt brukernivå per bruker er at man kan
skreddersy rettigheter for hver enkelt brukergruppe. En salgssjef må kanskje ha
administratorrettigheter til salg-delen av systemet, men ikke nødvendigvis
administratorrettigheter til bruker-delen.
Prosjekter
Systemet skal ha oversikt over prosjekter, med tilhørende kontaktinformasjon. Brukere og
salg skal tilhøre ett og bare ett prosjekt.
Kontaktpersoner
For mediebyrå og kunder skal systemet ha oversikt over kontaktpersoner med tilhørende
kontaktinformasjon. En kontaktperson kan være kontaktperson for flere kunder/byråer.
Notater
For salg, kunder og mediebyrå skal systemet ha oversikt over notater. Dette skal være korte
tekster knyttet til gitt salg/kunde/byrå. Notater skal ha informasjon om innhold, hvilken
bruker som opprettet det, og tidspunktet det ble opprettet.
Ikke-funksjonelle krav• Systemet skal ikke inneholde unødvendige patologiske avhengigheter
• Systemet skal enkelt kunne videreutvikles
• Brukergrensesnittet skal speile Propells brukergrensesnitt
• Brukergrensesnittet skal være interaktivt og deler av sider skal kunne oppdateres
asynkront
• Systemet skal ikke være for sterkt knyttet til database-teknologi
• Systemet skal kunne deles opp i uavhengige moduler som kan settes sammen til en
skreddersydd pakke
• Systemet skal være lett å deployere
• Systemet skal være sikkert og stabilt
BrukerhistorierBrukerhistoriene er generelt skrevet på formen
«Som en [brukerrolle], vil jeg [handling] (slik at [resultat])»
Siden systemet kan definere brukerroller per delsystem er brukerrolle beskrevet som
[delsystem]-[brukernivå]
Hvis delsystem ikke er spesifisert så menes det at brukernivået er globalt for hele systemet.
Viktighet og kompleksitet er rangert på en skala fra 0 til 10 (hvor 10 er høyest).
ID Brukerhistorie Viktighet Kompleksitet1 Som en bruker, vil jeg logge inn med e-post og passord,
slik at jeg får tilgang til systemet.10 7
2 Som en administrator, vil jeg opprette en ny bruker,slik at brukeren kan logge inn å få tilgang til systemet.
10 6
3 Som en administrator, vil jeg slette en bruker,slik at data om brukeren fjernes fra database og bruker ikke lengre kan logge inn.
10 5
4 Som en bruker med brukerrolle X, vil jeg ha tilgang til Yhvor brukerrollen X definerer brukernivået på Y til «Bruker»
10 5
5 Som en bruker med brukerrolle X, vil jeg slette og redigere elementer fra Yhvor brukerrollen X definerer brukernivået på Y til «Administrator»
10 5
6 Som en salg-bruker vil jeg kunne se alle salg
10 4
7 Som en salg-brukervil jeg kunne legge til et nytt salg
10 4
8 Som en salg-brukervil jeg kunne redigere eller slette mine egne salg
10 4
9 Som en salg-administratorvil jeg kunne slette salg
9 4
10 Som en kunde-brukervil jeg kunne se alle kunder
8 4
11 Som en kunde-brukervil jeg kunne legge til nye kunder
8 4
12 Som en kunde-administratorvil jeg kunne slette eller redigere kunder
8 4
13 Som en byrå-brukervil jeg kunne se alle byrå
8 4
14 Som en byrå-bruker 8 4
vil jeg kunne legge til nye byrå15 Som en byrå-administrator
vil jeg kunne slette eller redigere byrå8 4
16 Som en bruker, vil jeg kunne ta kunde-relasjonen for mitt prosjekt
4 5
17 Som en bruker,vil jeg kunne ta byrå-relasjonen for mitt prosjekt
4 5
18 Som en prosjekt-administrator,vil jeg kunne knytte en bruker til et prosjekt
4 5
19 Som en prosjekt-administratorvil jeg kunne opprette nye prosjekter
5 5
20 Som en prosjekt-administratorvil jeg kunne slette eller redigere prosjekter
5 5
21 Som en kunde-brukervil jeg kunne legge til kontaktpersoner for en kunde
6 6
22 Som en kunde-brukervil jeg kunne redigere eller slette kontaktpersoner for en kunde
6 6
23 Som en byrå-brukervil jeg kunne legge til kontaktperson for et byrå
6 6
24 Som en byrå-brukervil jeg kunne redigere eller slette kontaktpersoner for et byrå
6 6
25 Som en salg-bruker,vil jeg kunne legge til notater for et salg
4 5
26 Som en kunde-bruker,vil jeg kunne legge til notater for en kunde
4 5
27 Som en byrå-bruker,vil jeg kunne legge til notater for et byrå
4 5
28 Som en bruker, vil jeg kunne redigere eller slette mine egne notater
5 5
29 Som en bruker,vil jeg kunne se alle notater andre brukere har laget
5 5
30 Som en bruker,vil jeg kunne logge ut,slik at jeg ikke lengre har tilgang til systemet
10 3
31 Som en bruker,vil jeg kunne endre mitt passord, e-post og profilbilde
8 4
32 Som en salg-bruker,vil jeg kunne generere rapport av et salg,slik at jeg får lastet ned en PDF-versjon av salget
4 8
33 Som en administrator,vil jeg kunne endre brukerrolle til brukere
8 4