Kommentarer til eksamensoppaven 02.06.2008 - Brukte klær


Eksempel på løsning:

Get Adobe Flash player

Planlegging:

Når man skal planlegge hvordan slike oppgaver kan løses, er det lurt å bruke papir og blyant, tavle eller flip-over til å lage skisser og figurer, eksempelvis:

Skermbilder:

Bestilling:

Betaling:

Variabler og data:

Brukergrensesnitt:

Variabelnavn: Datatype: Kommentarer:
Frame: Bestilling    
bildeviser fl.containers.UILoader Viser bilde av varer
bakoverBtn, foroverBtn fl.controls.Button Blar i varer (lagret som XML i egen klasse Varelager
varenavnT, VareprisT Text Viser varenavn og varepris
antallSp fl.controls.NumericStepper Input: Bruker velger antall han bestiller
leggTilBtn fl.controls.Button Input: Bruker bestiller det som vises
sjekkUtBtn fl.controls.Button Input: Bruker er ferdig og går til utsjekking
     
Frame: Betaling    
navnTi, adresseTi, ... fl.controls.TextInput Input: Kundedata
kvitteringTa fl.controls.TextArea Utskrift av kvittering
bekreftBtn fl.controls.Button Input: Kunde bekrefter bestilling

Andre variabler og data:

Variabelnavn: Datatype: Kommentarer:
varelager Varelager Egen klasse i filen Varelager.as
bestilling Bestilling Egen klasse i filen Bestilling.as
bonus Boolean Har rett til bonus
bonusgitt Boolean Har brukt bonus
bildenr int Bilde/vare-nummer som vises

UML-diagram for egne klasser:

Kode (pseudokode):

Lyttere:

foroverKlikket()
   hvis bildenummer mindre enn største
      bildenr++
   oppdater bildeviser, varenavnT og vareprisT
bakoverKlikket()
   hvis bildenummer større enn 0
      bildenr++
   oppdater bildeviser, varenavnT og vareprisT
leggTilKlikket()
   hvis bonus
      legg til varenavn, varepris/2 og antall i bestilling
      sett bonus=false og bonusgitt=true
      gå til skjermbilde Betaling
   ellers
      legg til varenavn, varepris og antall i bestilling
sjekkUtKlikket()
   hvis sum>1000 og ikke bonusgitt
      sett bonus=true
      gi melding til bruker om bonusrunde
   ellers
      gå til skjermbilde Betaling

Lyttere i keyframe Betaling:

bekreftKlikket()
   hvis navn, adresse eller poststed tom
      gi feilmelding
   ellers hvis postnummer ikke har 4 tegn
      gi feilmelding
   ellers
      gi melding om at bestilling er gjort og avslutt programmet

Kode:

KeyFrame Bestilling:

stop();			//Stopper i keyframe Bestilling

/// --- Datamodell:
var varelager:Varelager = new Varelager();
var bestilling:Bestilling = new Bestilling();
		
/// --- Forretningslogikk: --- ///
var bildenr: int = 0;
var bonus:Boolean = false;
var bonusgitt:Boolean = false;
	
// Må vente til data er lastet før vi legger navn, pris og bilde
// inn i brukergrensesnittet for varenummer 1:
varelager.getLoader().addEventListener(Event.COMPLETE,varelagerKlart);

function varelagerKlart(evt:Event):void {
	varenavnT.text = varelager.getNavn(0);
	vareprisT.text = ""+varelager.getPris(0);
	bildeviser.source = varelager.getBilde(0);		
	meldingT.text="";	//Blanker meldingsfelt
}//varelagerKlart()

/// --- Lyttere: --- ///
bakoverBtn.addEventListener(MouseEvent.CLICK, bakoverKlikket);
foroverBtn.addEventListener(MouseEvent.CLICK, foroverKlikket);
leggtilBtn.addEventListener(MouseEvent.CLICK, leggtilKlikket);
sjekkutBtn.addEventListener(MouseEvent.CLICK, sjekkutKlikket);

function foroverKlikket(evt:Event):void {
	if (bildenr<(varelager.getAntallVarer()-1)) {
		bildenr++;
	}//if
	bildeviser.source = varelager.getBilde(bildenr);
	varenavnT.text = varelager.getNavn(bildenr);
	vareprisT.text = ""+varelager.getPris(bildenr);
}//foroverKlikket()
		
function bakoverKlikket(evt:Event):void {
	if (bildenr > 0) { bildenr--; }
	bildeviser.source = varelager.getBilde(bildenr);
	varenavnT.text = varelager.getNavn(bildenr);
	vareprisT.text = ""+varelager.getPris(bildenr);
}//bakoverKlikket()

function leggtilKlikket(evt:Event):void {
	if (bonus) {
		bestilling.leggTil(varenavnT.text, int(vareprisT.text)/2, 1);
		bonus = false;
		bonusgitt = true;
		gotoAndPlay("Betaling");	//Sjekker ut i keyframe Betaling
	}else{
		bestilling.leggTil(varenavnT.text, int(vareprisT.text), antallSp.value);
	}//if
	trace(""+bestilling.getSum());
}//leggtilKlikket()

function sjekkutKlikket(evt:Event):void {
	if ( (bestilling.getSum() > 1000) && (!bonusgitt) ) {
		bonus = true;
		meldingT.text="Bonus!...";
	}else {
		gotoAndPlay("Betaling");
	}//if
}//sjekkutKlikket()

 

KeyFrame Betaling:

stop();

kvitteringTa.text=bestilling.getKvittering();

bekreftBtn.addEventListener(MouseEvent.CLICK, bekreftKlikket);

function bekreftKlikket(evt: Event): void {
	kvitteringTa.text=bestilling.getKvittering();
	if(  
	     (navnTi.length<5)     ||
	     (adresseTi.length<5)  ||
		 (poststedTi.length<5) ||
		 (postnummerTi.length!=4)   )
	{
		kvitteringTa.appendText("\n\nDu må oppgi navn og adresse og korrekt postnummer!");
	} else {
		kvitteringTa.appendText("\n\n *** Bestilling Sendt ***");
	}//if
}//bekreftKlikket()

Klassen Varelager i Varelager.as:

Skisse av hvordan en slik klasse skrives:

package {

	public class Varelager {
		
		private var varelager: XML = null;
		...
		
		public function Varelager():void {
			...
		}//constructor
		
		public function getNavn(nr: int):String {
			...
			return ...
		}//getNavn()
		
		public function getPris(nr: int):Number {
			...
			return ...
		}//getPris()
				
		public function getAntall(nr: int):int {
			...
			return ...
		}//getAntall()

		public function getBilde(nr: int):String {
			...
			return ...
		}//getBilde()

		public function getAntallVarer():int {
			...
			return ...
		}//getAntallVarer
		
		public function getLoader():URLLoader {
			return xmlLoader;
		}//getLoader()
		
		// private:
		private function varerLastet(evt:Event):void {
			...
		}//varerLastet()
		
	}//class Varelager
	
}//package

Ferdig kode:

package {
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	/**
	 * Varelager klasse
	 *    Henter varelager fra filen klar.xml og legger i variabel varelager.
	 * Interface:
	 *    getNavn(nr:int):String
	 *    getPris(nr:int):Number
	 *    getAntall(nr:int):int
	 *    getBilde(nr:int):String
	 *    getAntallVarer():int
	 *    getLoader():UILoader			For å henge på lytter og vite når ferdig.
	 * @author Ulven
	 */
	public class Varelager {
		
		private var varelager: XML = null;
		private var xmlURL: URLRequest = new URLRequest("klar.xml");
		private var xmlLoader:URLLoader = new URLLoader(xmlURL);
		
		public function Varelager():void {
			xmlLoader.addEventListener(Event.COMPLETE, varerLastet);
		}//constructor
		
		public function getNavn(nr: int):String {
			if ( varelager == null) {
				return "";
			}else {
				return varelager.vare[nr].navn;
			}//if 
		}//getNavn()
		
		public function getPris(nr: int):Number {
			if ( varelager == null) {
				return -1.0;	//feil
			}else {
				return varelager.vare[nr].pris;
			}//if
		}//getPris()
				
		public function getAntall(nr: int):int {
			if ( varelager == null) {
				return -1;
			}else {
				return varelager.vare[nr].antall;
			}//if 
		}//getAntall()

		public function getBilde(nr: int):String {
			if ( varelager == null) {
				return "";
			}else {
				return varelager.vare[nr].bilde;
			}//if 
		}//getBilde()

		public function getAntallVarer():int {
			return varelager.vare.length();
		}//getAntallVarer
		
		public function getLoader():URLLoader {
			return xmlLoader;
		}//getAntallVarer()
		
		// private:
		private function varerLastet(evt:Event):void {
			varelager = XML(evt.target.data);
		}//varerLastet()
		
	}//class Varelager
	
}//package

Klassen Bestilling i Bestilling.as:

package {
	
	/**
	 * Klasse Bestilling:
	 * Samler opp bestillinger i assosiativ tabell.
	 * Interface:
	 *    leggTil(navn,pris,antall);	Legger til ny enkeltbestilling
	 *    getSum():Number				Regner ut totalsummen så langt
	 *    getKvittering():String			Lager kvittering av hele bestilling
	 * @author Ulven
	 */
	
	public class Bestilling {
		//Tabell med bestillinger
		private var bestilling: Array = new Array();
		
		public function Bestilling() {
			//Her kunne vi gjort eventuell initiering av klassen.
			//(Sette opp/klargjøre ting...)
		}//constructor
		
		/* Metode for å legge inn data etterhvert */
		public function leggTil(navn:String, pris:Number, antall:int):void {
			var delbestilling: Object = new Object();
			delbestilling.navn = navn;
			delbestilling.pris = pris;
			delbestilling.antall = antall;
			bestilling.push(delbestilling);
		}//leggTil()
		
		/* Metode for å finne tolasummen så langt.
		 * Trenger for å sjekke om vi får bonus
		 */
		public function getSum():Number {
			var sum: Number = 0.0;
			for (var i:int = 0; i < bestilling.length; i++) {
				sum += bestilling[i].pris * bestilling[i].antall;
			}//for
			return sum;
		}//getSum();
		
		/* Metode for å lage en streng med hele
		 * kvitteringsutskriften
		 */
		public function getKvittering():String {
			
			var kvittering:String = "Kvittering:\n";
			
			for (var i:int = 0; i<bestilling.length; i++) {
				kvittering += bestilling[i].navn + "\t\t" + 
							  bestilling[i].pris + "\t\t" +
							  bestilling[i].antall+"\t\t" +
							  bestilling[i].pris * bestilling[i].antall + "\n";
			}//for
			kvittering += "Totalt: \t\t"+this.getSum();
			
			return kvittering;
		}//toString()
		
	}//class Bestilling
	
}//package

Test av klasser:

En av fordelene med å legge kodedetaljer inn i egne klasser som Varelager og Bestilling,
er at vi kan teste dem uten å lage noe brukergrensesnitt.

Vi kan bare lage en ny Flash-applikasjon testklasser.fla og skrive og teste følgende
testkode uavhengig av og uten å ha laget noen andre deler av den endelige applikasjonen:

/**************************************
   Testkode for å teste klassene:
      Varelager
      Bestilling
***************************************/

/// --- Test av klassen Bestilling: --- ///

var bestilling: Bestilling = new Bestilling();

bestilling.leggTil("plagg",5000,10);
bestilling.leggTil("plagg 2",7000,5);
bestilling.leggTil("plagg 3", 9000,3);

trace();

trace( "Totalsum: "+bestilling.getSum());

trace(bestilling.getKvittering());




trace(); trace();  //tar noen linjeskift




/// --- Test av klassen Varelager: --- ///

var varelager: Varelager = new Varelager();

var loader = varelager.getLoader();

loader.addEventListener(Event.COMPLETE,varelagerLastet);

/* Skriver ut hele varelager når det er ferdig lastet */
function varelagerLastet(evt: Event):void {
	var storrelse: int = varelager.getAntallVarer();
	for(var i: int = 0; i<storrelse; i++) {
		trace( varelager.getNavn(i),varelager.getPris(i),varelager.getAntall(i));
	}//for
}//varelagerLastet()

Dette vil produsere følgende output:

Totalsum: 112000
Kvittering:
plagg	5000	10	50000
plagg 2	7000	5	35000
plagg 3	9000	3	27000
Totalt: 112000


jakke 1500 5
bukse 700 7
lue 200 14