R15 PaSOOS (22/04-2008)

Relaterede dokumenter
dsoftark E2007 Gruppe 14: Anders, Troels & Søren 15. november 2007 Rapport til a. 1 'TDD rytmen'

dsoftark E2007 Gruppe 14: Anders, Troels & Søren 15. november 2007 Rapport til a. 1

Kursus i OOP og Java. Kursus i Objektorienteret programmering i Java

Hvordan gør de professionelle?

DANMARKS TEKNISKE UNIVERSITET

Programmering C Eksamensprojekt. Lavet af Suayb Köse & Nikolaj Egholk Jakobsen

Løsning af møntproblemet

ZBC Vordingborg Marcus Rasmussen, Oliver Meldola, Mikkel Nielsen 17/ The Board Game

Skriftlig eksamen i Datalogi

Ide med Diff. Mål. Tidsplan. 1.uge: 2.uge:

//Udskriver System.out.println("Hej " + ditfornavn + " " + ditefternavn + "."); System.out.println("Du er " + dinalder + " aar gammel!

Martin Geisler. Uge 49, 2001

Svendeprøve Projekt Tyveri alarm

Test med JUnit 3. Denne artikel introducerer JUnit 3. Den forklarer ideen med JUnit. Og den viser hvordan man konkret bruger det.

Exceptions i Delphi. Try except

Mircobit Kursus Lektion 3 (Du skal her vælge Lets Code Og nederst Microsoft Block Editor.)

SmartFraming Et vindue til nationale sundhedssystemer. Version 3.0

Hvorfor skal vi bruge objekt orienteret databaser?

Undo Jo flere jo bedre! 1/9

At udfolde fortællinger. Gennem interview

Begreber om Godt Software

Nej. Ikke RUC koden, men nogle koder bliver delt. Kæresten kender koden til Netflix. Nej.

Systematisk testning af program til udregning af mellemskat

Stine Dorry Meulengracht Madsen Rapport Multimedie og kommunikation

1-1 Usability evaluering af den simple udgave

Dokumentation til Computerspil

Greenfoot En kort introduktion til Programmering og Objekt-Orientering

DM507 Algoritmer og datastrukturer

120 ords-tæppet. På sporet af ordet

Analyse af PISA data fra 2006.

b) Udvid din implementation af forme til at understøtte.equals. To objekter af samme form er ens hvis de har samme værdier i felterne.

Billedbehandling. Roll-up banner til Kvickly i Ribe

Rekursion C#-version

Partners er et spil med mange klare regler og en masse uskrevne regler, som varierer alt efter, hvem man spiller sammen med.

Børnepanel Styrket Indsats november 2016

Specialiseringen Rapport Lavede Af Rasmus R. Sørensen Side 1 af 6

DM507 Algoritmer og datastrukturer

IT opgave. Informationsteknologi B. Vejleder: Karl. Navn: Devran Kücükyildiz. Klasse: 2,4

Indhold. 2 Kommunikation/IT afsluttende opgave

Jeg ville udfordre eleverne med en opgave, som ikke umiddelbar var målbar; Hvor høj er skolens flagstang?.

DM507 Algoritmer og datastrukturer

Det fremgik af sagens akter at en plejefamilie den 8. marts 2005 modtog en dengang 8-årig dreng, A, i familiepleje.

Sortering. Eksempel: De n tal i sorteret orden

SYSTEMDOKUMENTATION AF POC

NYHEDSBREV. 80 % fejlrate? Carry on!?

A Profile for Safety Critical Java

EA3 eller EA Cube rammeværktøjet fremstilles visuelt som en 3-dimensionel terning:

Forelæsning Uge 2 Torsdag

Det Nye Testamente lyd-app. v. Stefan Lykkehøj Lund

Sortering af information er en fundamental og central opgave.

Forelæsning Uge 2 Torsdag

Abstrakte datatyper C#-version

Spil Master Mind. Indledning.

Sortering. Eksempel: De n tal i sorteret orden

Sortering af information er en fundamental og central opgave.

DM507 Algoritmer og datastrukturer

ZBC Vordingborg Marcus Rasmussen, Oliver Meldola, Mikkel Nielsen 17/ The Board Game

IndentifyIT Survey Rapport

Portfolio. Udvikling af min portfolio Link til portfolio: Michell Aagaard Dranig

Projekt 2, Banner. Project 02 - Banners. Gruppenummer: 8

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 2

Rygestop muligheder - og alt det der holder os tilbage

DM507 Algoritmer og datastrukturer

LEVERANCE 1.3. Model for kvalitetssikring

Mandags Chancen. En optimal spilstrategi. Erik Vestergaard

Elasund Rules Forberedelse Marker byggeområdet

3. Om skalamønstrene og den indfoldede orden

Accelerace og Green Tech Center kommer nu med et unikt tilbud om udvikling af din virksomhed Green Scale Up

Brøk Laboratorium. Varenummer

DM507 Algoritmer og datastrukturer

Vurder samtalens kvalitet på følgende punkter på en skala fra 1-5, hvor 1 betyder i lav grad og 5 betyder i høj grad.

Rapport: Kredshjemmesider i Danske Baptisters Spejderkorps. Jan 2012

Udfordringer og problemstillinger. En liste over de udfordringer og problemstillinger, der er ved Java og JEE udvikling

Grafisk workflow. bl.udbudsnet.dk

Matematik, maskiner og metadata

HHBR. Design. Kvalitets vurdering. Opgaven. Målgruppe og Budskab. De Grafiske valg

Software Dokumentation

Forelæsning Uge 4 Torsdag

DM536. Rapport og debug

Forelæsning Uge 4 Mandag

Arbejdsblad. Indhold. 27. maj 2010 A Projektplanlægning 1. 2 Samarbejdet i gruppen 3. 3 Samarbejdet med vejlederne 5

DM517:Supplerende noter om uafgørlighedsbeviser:

Softwaretest. - også af "ikke testbar" software. DAPUG erfamøde 7. marts 2012 Thomas Vedel, Thomas Vedel Consult thomas@veco.

Rapport om brugerevaluering af pilotprojektet Bedre Breve i Stevns Kommune

Guide 7 tips til organisatorisk implementering.

Undervisningsbeskrivelse

Læringsprogram. Christian Hjortshøj, Bjarke Sørensen og Asger Hansen Vejleder: Karl G Bjarnason Fag: Programmering Klasse 3.4

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

Sta Stem! ga! - hvordan far vi et bedre la eringmiljo? O M

Vurder samtalens kvalitet på følgende punkter på en skala fra 1-5, hvor 1 betyder i lav grad og 5 betyder i høj grad.

Gennemsnit og normalfordeling illustreret med terningkast, simulering og SLUMP()

Hvad er Objekter - Programmering

Lærervejledning. Beskriv ideen med spillet i plenum, herunder dets funktion og de tre vigtigste pointer med spillet:

Online billede filtrering

Portfolio. Fremstilling af den bedste hjemmelavede tykmælk. 1 Hypotesedannelse. Lav jeres hypotese Præsentation af hypotese

Indhold: Spillebræt 5 hære med 40 infanteri-, 12 kavaleri- og 8 artillerienheder i hver 43 kort 2 referencekort 5 terninger

Arbejde med Regioner Lister, Playlists, og Cutlists i Sound Forge Pro

[AFSLUTTENDE OPGAVE I KOM/IT]

Transkript:

HotTargui projektet - Kasper Bo Larsen & Martin Skov Test case Status Rækkefølge Spillet er slut efter 25 runder færdig (MSN) Rød spiller starter færdig (MSN) Grøn kommer efter rød, blå efter grøn, gul efter blå færdig (MSN) Flyt før køb (Der skal flyttes før der købes kameler) færdig (KLA) Spiller kan flytte ikke implementeret Spiller kan kun flytte egne brikker færdig (KLA) Træk er gyldigt undervejs (KLA) Brikker kan kun sættes på home base færdig (KLA) Kameller dræber en-til-en færdig (MSN) Revenue udbetales korrekt færdig (KLA) Spiller flytter brik til ikke tidligere ejet tile, denne tilhører nu spilleren færdig (KLA) spiller flytter brik til en anden spillers felt (ingen kameler), feltet skifter ejer færdig (MSN) Tjek at Tiles er anbrangt korrekt færdig (KLA) Startkondition: 10 coins i kassen færdig (KLA) Startkondition: 10 kameler på basen færdig (KLA) Ej muligt at bevæge sig ind i saltsø færdig (KLA) Prøver at flytte flere kameler end der er til rådighed færdig (KLA) Ejeren af saltminen er vinderen færdig (MSN) Der kan ikke købes flere kameler end der er penge i kassen færdig (KLA) Prøver at flytte -1 kameler færdig (KLA) Prøver at flytte 0 kameler færdig (KLA) Test cases i kursiv er kandidater til Triangulering Da antallet af kandidater til testlisten (AlphaTargui) i første iteration nåede over 20, måtte vi tage stilling til spørgsmålet om samtlige test cases reelt var nødvendige. På den lange bane er det næppe nogen tvivl om, at den tidsmæssige gevinst ved at kode- og logikfejl bliver fanget så tidligt i forløbet som mulig er betragtelig. Modsætningsvis skal vi sandsynligvis bruge en del tid til at tilpasse test case'ene, efterhånden som spillet bliver mere og mere avanceret. Konkret eksempel : Lad os for diskutionens skyld formode, at det kunne tænkes at vi lavede fejl, og således anbragte et par af brikkerne forkert på pladen. Det vil næppe kræve megen fantasi at forestille sig de tilsyneladende umulige fejlsituationer, som dette vil kunne give anledning til senere i projektet. Dette taler helt klar til fordel for at bruge ressourcer på at skrive en test case, som validerer placeringen af brikkerne. Alternativ kunne selve spillet indeholde et selvdiagnosticeringsmodul. Modsætningsvis har vi en formodning om at placeringen af brikkerne næppe vil forblive statisk. I så fald vil valideringsmetoden kun være af begrænset værdi, idet den så kun kan benyttes i Alphavarianten. Test af og validering af data i kernesystemet HBC argumenterende ved seminaret i starten af april 2008 for at klasserne i kernesystemet principielt ikke skal validere sine data, idet dette bør foretages i interfacet. Pricipielt er dette synspunkt korrekt, men det er vores erfaringer fra tidligere projekter, at man ofte ser at andre projekter kobler sig direkte på kernesystemet frem for at benytte de eksisterende snitflader. Årsagen er som regel at de eksisterende snitflader, ikke opfylder de ønsker, som de nye projekter har. Den korrekte løsning er naturligvis at tilpasse snitfladerne, men grundet tidspres vælger man ofte at omgå snitfladerne. Da et at formålene med dette kursus er at lave fleksibel software, har vi valgt at sikre, at en omgåelse af snitfladerne skal være mulig uden at kompromitere datavalideringen. Dette øger naturligvis risikoen for at man fristes til R15 Martin Skov Nielsen & Kasper Bo Larsen 1

at vælge den "nemme" løsning frem for den korrekte løsning, men det er sjældent udviklerne, der træffer de strategiske beslutninger, men det er altid udviklerne, der skal leve med koncekvenserne. Men i den perfekte verden, hvor man har masser af tid, ingen deadlines og masser af ressourcer, så ja - så bør valideringen af data foregå før data rammer domænet. Tool support Jeg savner meget muligheden for at kunne debugge en enkelt test case. Jeg havde meget svært ved at gennemskue en fejl i "FlytTilSaltsoe" metoden. Med det begrænsede kendskab jeg har til test cases i et java miljø, valgte jeg at tilføje en del asserts i test casen, hvilket gjorde det vanskeligt at gennemskue formålet med test casen. Pricipet er at en test case skal være så simpel som muligt. En af de features i TestDriven.Net (et Unit Test add-on til Visual Studio) som jeg savner er Code Coverage. Hermed menes en oversigt over hvor mange % af koden der bliver benyttet i test case'ne. Det er muligt at se (farvekodet) de dele af kode som ikke beføres af mine test cases. Det giver ro i sjælen når den eneste kode der ikke testes er exceptions handlerkoden. Begge værktøjer findes utvivlsomt til java IDE'erne men specielt Code Coverage bør omtales og evt. demonstreres i dette kursus. Faren ved fejlagtige slutninger Implementationen af test casen "FlytTilSaltsoe" er relativ simpel: I runde 1 flytter Rød spille fra (0,0) til (1,0), turen går videre til Grøn spiller som intet fortager, det samme er tilfældet med Blå og Gul spiller. Runden er nu færdig og skatterne inddrives. Nu er det så Røds tur igen og Rød kan nu flytte fra (1,0) til (2,2) som er en saltsø. Dette træk burde blive afvist, da reglerne forbyder spillere at rykke ind i saltsøen. Test case var en success for game.move returnerede false ganske som forventet, og så er alle jo glade. Problemet er bare at grunden til at metoden returnede false, ikke var relateret til saltsøen, men derimod at spillet ikke var i Move state, det var i endrount state. Ergo havde vi her en ægte falsk positiv. Som en erfaring til næste gang må vi konstatere at valideringen skal være langt mere præsis. Den værdi der valideres skal være unik, forstået på den måde at værdien ikke må kunne fremprovokeres af andre input. R15 Martin Skov Nielsen & Kasper Bo Larsen 2

Problemer med at udnytte trianguleringsteknikken Vi havde udtaget Revenue udbetales korrekt test case'n som primærkandidat til demostration af trianguleringsteknikken, men vi havde ret vanskeligt ved at komme på en model hvor triangulering fungerende. Vi endte med følgende test cases : @Test public void TestAfCollectTaxesNoMoves() // formål: at gennemløbe en runde uden at flytte overhovedet. Hver spiller bør blive tilskrevet 4 coin for at "passere" start System.out.println("\r\n TestAfCollectTaxesNoMoves"); game.rolldie(); Player redplayer = game.getplayerinturn(); asserttrue(redplayer.getcolor() == PlayerColor.Red); assertequals(redplayer.getcoins(), 14); og den udvideden udgave : @Test public void TestAfCollectTaxes() System.out.println("\r\n TestAfCollectTaxes"); game.rolldie(); game.move(new Position(0,0),new Position(1,1),2); Player p = game.getplayerinturn(); asserttrue(p.getcolor() == PlayerColor.Green); game.move(new Position(0,6),new Position(1,6),2); boolean res = game.move(new Position(6,0),new Position(5,0),2); asserttrue(res == true); game.move(new Position(6,6),new Position(6,5),2); asserttrue(game.getplayerinturn().getcoins() == 17); Player greenplayer = game.getplayerinturn(); asserttrue(greenplayer.getcolor() == PlayerColor.Green); asserttrue(game.getplayerinturn().getcoins() == 16); Player blueplayer = game.getplayerinturn(); asserttrue(blueplayer.getcolor() == PlayerColor.Blue); asserttrue(game.getplayerinturn().getcoins() == 17); Player yellowplayer = game.getplayerinturn(); asserttrue(yellowplayer.getcolor() == PlayerColor.Yellow); asserttrue(game.getplayerinturn().getcoins() == 15); Ideen er at test casen TestAfCollectTaxesNoMoves giver os et referancepunkt, idet hver spiller bliver i sin egen settlement, hvilket burde give 4 coins i skatteindtægter. R15 Martin Skov Nielsen & Kasper Bo Larsen 3

Via Fake It og derefter Obvious Implementation var det ret simpelt at få den test case på plads. Den udvidede udgave TestAfCollectTaxes var en større mundfuld. Selve conceptet er ret simpelt: Gennemspil en runde, hvor hver spiller overtager yderligere en brik. Selve beregningen af den forventerede skatteinddrivning var triviel. Implementering af CollectTaxes metoden krævede - trods forventning om det modsatte - en del anstrengelser, primært i forbindelse med at holde fokus på den konkrete opgave. Undervejs var der flere gange tilløb til at optimere koden og fjerne identisk kode, hvilket indikerer at vi burde have nedbrugt opgaven i mindre elementer. Først da vi var blevet færdig med CollectTaxes test casen begyndte vi at overveje om metoden retteligt hørte hjemme, som en metode på AlphaTargui, idet opgaven med at beregne skatter kunne skilles ud i sin egen klasse. Et argument imod en udskillelse i sin egen klasse, er at denne klasse ene og alene arbejder med data som hører hjemme i getboarditerator, hvilket indikerer en kraftig binding. Kodekvalitet inden refaktoring Som det tydeligt fremgår er koden yderst primitiv. En af de erfaringer vi har fået af at arbejde med TDD er, at både testog produktionkoden ofte er meget simpel, "grim" og fyldt med gentagelser. Vi har en formodning om, at det er en generel tendens og ikke blot et tegn på forfatternes manglede evner. Grunden til koden virker ustruktureret og uelegant skal sandsynligvis findes i, at TDD ligger op til at fokusere på at få test casen til at virke. Denne fokusering har den bivirkning, at man ikke undervejs i rytmen stopper op for at restrukture koden, idet dette vil bryde rytmen, som er grundstenen i TDD. Dette faktum demonstrerer at refactoring elementet i TDD bestemt ikke er en optionel del af TDD, men en absolut nødvendighed. Fordelen er at refactoringen sker under sikre betingelser, idet den eksisterende test case sikrer at omstruktureringen af koden, som minimum leverer samme funktionalitet. Vi har, for at pointere vores erfaring, valgt at undlade at refaktorere både test og produktionskoden, som ellers er foreskrevet, som sidste aktivitet i implementationen af en test case. Test cases kompleksitet En anden erfaring vi har gjort os, som formentlig kun kan løses med mere erfaring, er at test cases har det med at blive mere komplekse end de var tiltænkt. Et eksempel er testen, som skal finde vinderen. Den skal løbe et helt spil igennem før, man kan udpege en vinder, hvilket gør test casen ganske uoverskuelig, og absolut kun brugbar, da vi ved at de andre cases giver grønt lys for at køre. Selv om den spiller spillet igennem ved hjælp af en løkke, så er casen meget stor. Det giver naturligvis anledning til at overveje om man skulle uddelegere noget af den til andre. Men omvendt så ved vi at de andre cases vil virke, hvis vi blot sørger for at lave nogle gyldige træk undervejs. Det viste sig også at det ikke krævede meget arbejde, at få casen til at give grønt lys. Men vedligeholdelse af den pågældende case kan blive temmelig krævende. Men for at igen at understrege vores pointe ovenfor omkring refaktorering, så er den ikke blevet ændret. Husk refaktorering i det store perspektiv En af de vigtigste øvelser test driven development, er at holde fokus på målet og holde rytmen. Men hvis man begynder at tænke roller ind som interfaces og udelegering af ansvar, så kommer man hurtigt til at rutsje ud til siden, og mister fokus på målet selvom man måske egentlig syntes at man har en fin rytme. R15 Martin Skov Nielsen & Kasper Bo Larsen 4

Erfaringen fra dette kursus siger os, at man hellere skal ramme målet først. Selvom det måske så ikke lige håndterer ansvarsfordeling, som det for eksempel ses af den kode der følger med rapporten her. Her er målet nået ved hjælp af TDD med fuldt fokus på målstregen og udsving til overvejelser om roller og ansvar. Først da vi havde opnået den ønskede funktionalitet, begyndte vi at overveje hvilke dele der skulle skilles ud. F.eks. kunne vi uden at vi jo ved noget om det forestille os at man ville ændring beregningen af skatter eller angrebsstrategi. Derfor vil vores fokus nu ligge i at refaktorere i det store perspektiv og ikke kun rydde op og fjerne kodeduplikering, men refaktorerer hele systemdele ud som delegates. Design patterns En anden ting som også skal overvejes i refaktoreringen er hvilke design mønstre, som bedst muligt understøtter vores slutprodukts fleksibilitet. Men det er endnu et element, som for udviklere med vores erfaring i TDD vil sætte en bremseklods på rytmen. Med noget mere erfaring i både mønstre og TDD, så vil vi mene at vi per refleks begynder at indarbejde nogen flere tanker om design mønstre i vores rytme, men indtil da bliver det en del af refaktoreringen. Vi vil jo bruge mønstrene sammen med 3-1-2 processen til at se på hvad og hvor, vi vil uddelegere. Således at vi opnår en fleksibel og pålidelig software. Systematisk test Hottargui Æklivalensklasser Dimension Invalid Partition Valid partition Strategical Value of Tile <0 [1], >5 [2] 0-5 [3] Dice value <1 [4],>6 [5] 1-6 [6] Number of defenders <1 [7] F(x) > antal kameler [8], F(x) = ((int)(strategic Value + Antal øjne)/2)) F(x) <= antal kameler[9] Inputparameterne er de to uafhængige størrelser Strategic Value og antallet af øjne på terningen. Af hensyn til validering af returværdien (hvor mange kameler der skal fjernes) blive vi nødt til af kigge på antallet af kameler på det angrebne felt. Grunden er at summen af Strategic Value + antal øjne delt med to faktisk kan være større end det antal kameler som forsvarer feltet, og funktionen derfor bliver nødt til at tage højde for denne betingelse. Eksempel: 2 kameler forsvarer feltet men Strategic Value + antal øjne angiver at der skal fjernes 4 kameler. Dette er ikke muligt og funktionen bliver derfor nødt til at ændre returnværdien til 2. Konceptet er at vi indtil alle valide partitioner er i brug skal findes den test case, som bruger så mange af de valide partitioner som muligt. Derefter skal de invalide partitioner testes én af gangen. Equivalence class Test case Expected output R15 Martin Skov Nielsen & Kasper Bo Larsen 5

[3]x[6]x[8] 10-((4+3)/2) 7 [3]x[6]x[9] 1- ((2+4)/2) 0 Spørgmålet om hvorvidt vi bør have test cases, som håndterer de usandsynlige tilfælde, så som at Strategic Value of Tile er et negativt tal, er så vidt vi kan se mest af alt et spørgsmål om applikationens formål og udviklernes holdning til emnet. Dersom en fejl i applikationen kan have alvorlige konsekvenser for omgivelserne vil vi anse det naturligt at selv de usandsynlige tilfælde omfattes af en test case 1. I dette tilfælde kan man næppe påstå at menneskeliv er på spil hvis Targui bryder ned, på den anden side er antallet af test cases ret begrænset, så vi har delt samtlige mulige test cases i to grupper, Must-haves og Nice-to-haves. Hvor Must-haves implementeres med det samme, og Nice-to-haves overlades til erhvervspraktikant en. Vi er i tvivl om, hvorvidt vores forudsætning angående antallet af forsvarer i ovenstående partitionstabel er korrekt. Spørgsmålet er om antallet af forsvarer skal være større end nul før end der er tale om at Attackalgoritmen kommer i brug. Vores design startede med at have indlejret brugen af Attack-strategien i Move delegaten, som modtog attack-strategien som parameter. På den med håndterer move delegaten situationen hvor spiller A flytter ind på et af spiller B ejet felt, som dog ikke nødvendigvis er forsvaret af en eneste kamel. Vi valgte dog undervejs at ændre vores design. Baggrunden for ændringen er beskrevet i afsnittet TDD i praksis. Alternativet er at Attack håndterer alle situationer hvor en spiller forsøger at flytter ind på et i forvejen ejeret felt. Da hovedformålet med Attack delegaten er, at opnå en abstration som er specialist i at håndtere angreb og de bagvedliggende rutiner, giver det ingen mening at attack også skal kunne håndtere de situationer hvor felterne blot skifter ejer uden dramatik. Grænsetilfældeanalyse Da hverken terningen eller den strategiske værdi umiddelbart tilbyder interessante grænsetilfælde indenfor de valide partitioner, kiggede vi i stedet på mulighederne for at finde noget interessant i forbindelse med antallet af forsvarer på den Tile der bliver angrebet. 1 Ifølge afsnit 25.5.5 Final Notes i RFSE anfører Myers at mange bugs findes i de invalide partitioner, men udviklere ofte ikke fanger disse. R15 Martin Skov Nielsen & Kasper Bo Larsen 6

Det ene tilfælde som vi umiddelbart fandt interessant, var når antallet af forsvarer var nul. Da vores implementation er designet således at denne situation ikke håndteres af Attack-algoritmen, men derimod af Move-algoritmen, er dette tilfælde heller ikke relavant. Observationer Vi har diskutteret hvorledes vi skal forholdes os til de metoder på f.eks. AlphaGame og BetaGame som er identiske, f.eks. CollectTaxes: private void CollectTaxes() //summ antal felter ejet af hver spiller int taxforred = 0; int taxforblue = 0; int taxforgreen = 0; int taxforyellow = 0; for(int i = 0; i < thetilelist.size(); ++i ) Tile t = thetilelist.get(i); int value = getvaluefortiletype(t); if( t.getownercolor() == PlayerColor.Red) taxforred += value; debug("red tilskrives " + value); debug("red har nu " + taxforred); else if (t.getownercolor()== PlayerColor.Blue) taxforblue += value; debug("blue tilskrives " + value); debug("blue har nu " + taxforblue); else if( t.getownercolor()== PlayerColor.Green) taxforgreen += value; else if (t.getownercolor() == PlayerColor.Yellow) taxforyellow += value; debug("yellow tilskrives " + value); debug("yellow har nu " + taxforyellow); StandardPlayer theplayer = (StandardPlayer)players[0]; theplayer.add(taxforred); theplayer = (StandardPlayer)players[1]; theplayer.add(taxforgreen); theplayer = (StandardPlayer)players[2]; theplayer.add(taxforblue); theplayer = (StandardPlayer)players[3]; theplayer.add(taxforyellow); R15 Martin Skov Nielsen & Kasper Bo Larsen 7

Reelt er der tale om Source Code copy og dermed har vi et potentialt vedligeholdelsesproblem, idet enhver rettelse til metoden skal synkroniseres med de samme metoder i de andre klasser. Med mere erfaring Vi nævnte tidligere, at vi gik let over refaktoreringen for ikke at bryde rytmen i vores TDD, men allerede nu må vi se, at vores teori ikke helt holder vand. Det har nemlig vist sig væsentlig mere tidskrævende at kravle tilbage i metoderne og refaktorisere dem end forventet. Det betyder jo netop at rytmen går helt i stå i den tid, hvor man refaktoriserer. Så vi må erkende at Kent Beck princip om at refactorisere i bund er måden, hvorpå man bedst holder rytmen. Ganske som det også blev diskuteret på seminaret d. 26-04-2008 Valg af mønstre For at sikre fleksibilitet i vores system, har vi valgt at uddelegere en række ansvarsområder fra game. F.eks. er ansvaret for at sætte spillepladen op uddelegeret. Det har vi gjort af to grunde: 1. Vi ønsker ikke at tildele mere ansvar end nødvendigt til AlphaGame 2. Udfra konceptet om at lade specialisterne klare arbejdet, som vi mener er oplagt her Vi har valgt at håndtere uddelegeringen med et strategy pattern, som ser ud som figuren nedefor: Det skal dog lige bemærkes at der på tegningen er en særlig implementation DeltaStrategy, som vi ikke pt. kender nødvendigheden af. Men pointen er at vise, hvor let det nu er at lave flere forskellige "boards" til HotTarqui. R15 Martin Skov Nielsen & Kasper Bo Larsen 8

De mange strategies land Efterhånden som vi fik arbejdet os igennem refaktoreringen, opstod der flere og flere forskellige strategier. Det førte os til ideen om at der måske kunne blive brug for forskellige strategier i forskellige sammenhæng - med andre ord: Det her skal nok kunne konfigureres. Så fat i et abstract factory: GameFactory, som kan oprette de forskellige strategier, som vi måtte have brug for i en given opsætning. UML afbildningen af vores abstract factory begynder allerede ved to konkrete factories, at blive uoverskueligt. Så yderligere diagrammer over mønsteret vil formentlig være bedst tjent med at blive opdelt. Diagrammet her kunne blive mere klart og informationgivende ved at blive delt i et alpha og beta diagram, men da vi her ønsker at vise mønsteret, har vi valgt at lade dem forblive samlet. Game <<interface>> GameFactory AlphaBoardSetup <<interface>> BoardSetupStrategy AlphaGameFactory BetaGameFactory BetaAttackStrategy <<interface>> AttackStrategy AlphaAttackStrategy AlphaMoveStrategy <<interface>> MoveValidationStrategy StandardDieRoll <<interface>> DieRoll BetaDeployValidator <<interface>> DeployValidator AlphaDeployValidator R15 Martin Skov Nielsen & Kasper Bo Larsen 9

At tænke i fleksibilitet For ikke at låse det framework, som HotTarqui startede som, så har vi valgt kun at tilføje enkelte funktioner i kodebasen, som så er tilgengængelig via interfaces - i de tilfælde hvor det skal kunne konfigureres i de enkelte versioner. Al implementation af forskellige versioner ligger så i individuelle implementations pakker. På den måde holder vi fast i indkapslingen i frameworket, og binder os ikke til en speciel version. Et par enkelte steder fandt vi nogle klasser, som blev standard funktionalitet for vores versioner, og dermed formentlig også vil blive brugt i fremtidige versioner. Men da vi ikke mener de bør være en dedikeret del af frameworket, da der jo er tale om implentation af dele af frameworket. Disse implementationer er tilgengæld blevet placeret i pakken standard, som vil rumme standard implementationer, der kan anvendes, hvis de dækker de behov man måtte have. TDD i praksis Som beskrevet tidligere så valgte vi undervejs at ændre vores design omkring move metoden. Det gjorde vi, fordi vi under udviklingen af BetaAttackStrategy oplevede vi effekten ved TDD. Det lykkedes faktisk at udvikle en fin algoritme, som kunne håndtere angreb med strategisk værdi og terning kast og som gav grønt i den første test case, hvor der bare blev angrebet til en af spillerne ikke havde flere kameler. Grønt test resultat - så skulle den jo være på plads... Men ak og ve. Næste test var så at angriberen skulle angribe to gange og så stoppe. Med det samme opdagede vi et problem, for hvordan stoppede vi lige angriberen? Det var ganske enkelt ikke muligt, da vi med fokus på at lave testen før grøn, ganske enkelt havde fået kodet algortimen uden om tilstandsmaskinen. En uheldig situation, som hurtigt blev opdaget med TDD. Resultatet I første omgang virkede det ikke som noget problem at ændre fejlen med tilstandsmaskinen, men det vidste sig at være noget vanskeligere end forventet at få ændret den, så alle krav kunne opfyldes. Faktisk blev refaktoreringen ganske omfattende og endte med at have betydning for både gameimplementationerne og movestrategy. Vi havde en snak om hvordan vi bedst fik placeret ansvaret for at håndtere tilstandsskift i forbindelse med angreb og flytning. Resultatet blev at vi valgte at lade game-implementationen håndtere disse, da vi lod vores move-delegates move-metode returne den nye state, som spillet skal være i. Herefter kan vi lade den enkelte game version håndtere tilstanden. Så ansvaret for tilstandshåndtering forbliver hos game. Faktisk gav refaktoreringen anledning til ændring i vores tilstandsdiagram, som nu ser således ud: R15 Martin Skov Nielsen & Kasper Bo Larsen 10

Generelle observationer At arbejde sammen hver for sig Denne gruppe har grundet bopæl på hver sin side af Storebælt haft rig lejlighed til at afprøve mulighederne for at arbejde sammen hver for sig. Den tekniske side har overhovedet ikke/ kun i ubetydlig grad givet anledning til problemer. Adskellige sites på internettet tilbyder gratis hosting af både kode, dokumenter mm. Vi valgt at benytte Google Code idet Kasper Bo Larsen (herefter KLAR) havde positive erfaring med Subversion samt at flere at java IDE'erne har glimrende integration hertil. KLAR valgte at benytte en Eclipse, hvor Martin Skov Nielsen (herefter MSN) valgte en NetBeans. Disse valg har så vidt vi kan bedømme ikke påvirket projektet på en mærkbar måde, så det tyder på at der er valgfrihed på dette område. R15 Martin Skov Nielsen & Kasper Bo Larsen 11

Dog har der i et par enkelte tilfælde været committed tilsyneladende fejlfri kode fra NetBeans, som ikke ville compile i Eclipse. Når der blev fejlsøgt i de klasser, som Eclipse meldtefejl på, så har der rent faktisk ligget en bug i klassen. Hvilket godt kan undre lidt, da alle tests virkede i NetBeans og projektet compilede. Udfordringen har helt klar været at etablere en fornuftig arbejdsgang, således at vi fik optimal udnyttelse af den medgående tid. Dette har ofte vist sig at være vanskeligt, idet vi ofte arbejdede på forskellige tidspunkter. Det har derfor i mange tilfælde været vanskeligt at diskutere en idé eller problem i gruppen. Denne sparring har vi måtte klare via email, instant messenging og lejlighedvis telefon. Det er klart vores holdning at denne form for afstadssamarbejde ikke vil kunne holde i en arbejdssituation, idet det bryder rytmen, når man ikke lige kan få afklaret en problemstilling med det samme. Ligeledes er det en showstopper at måtte vente på response omkring en ide, som man måske lige mangler et twist på, for at kunne færdiggøre eller implementere. Test driven development pro et contra Selv om vi efterhånden har arbejdet efter pricipperne i TDD de sidste 3-4 måneder, opdager vi til stadighed, at vi er "faldet i vandet". I 90% af tilfældene begynder vi at lave produktionskode uden at have unit testen på plads først. Fra et pragmatisk synpunkt betyder dette intet, blot man husker at lave test casen, inden man går videre til næste delopgave. Selv om vi ofte selv har måtte bruge denne løsning, tiltaler den os ikke. Den primære grund er at de enkelte metoder og komponenter tilsyneladende bliver mindre "skarpe" i forhold til de elementer, hvor vi har fulgt TDD takten. Det er mere reglen end undtagelsen, at vi må omskrive og refaktorere disse "uskarpe"/"uforkuserede" komponenter op til flere gange, inden de opnår en acceptabel kvalitet. Ud fra disse erfaringer har vi uddraget to hypoteser: 1. TDD fremgangsmåden kræver forholdsvis lang tids træning, inden man kan stå på egne ben. Dette kunne antyde at pair-programming sandsynligvis er en af de bedre måder at få metodikken indarbejdet på. 2. TDD fremgangsmådens krav, om at fokusere på et emne af gangen, giver tilsyneladende et klarere design på metode og klasse-niveau, idet den enkelte metode eller klasse er specialiseret til at opfylde en bestemt rolle. Bagsiden ved denne fremgangsmåde formodes at være, at man pga. det stærke fokus på enkeldelene muligvis ikke ser de store linier og dermed risikere at overse muligheder for at generalisere sin kode. Hvilket yderligere understøtter tesen om at det kræver længere tids træning, før man er rigtig moden i TDD. R15 Martin Skov Nielsen & Kasper Bo Larsen 12