Hvis man ikke kjenner til slike mønstre, hjelper det ikke å bruke et godt objektorientert språk og vite hva abstraksjon, innkapsling, arv og polymorfi er.
God programmering krever i tillegg kjennskap til hvordan teoretikere og praktikere gjennom lang erfaring har funnet mønstre for programmering som leder til gode løsninger.
Ideelt skal kommunikasjonen mellom bruker og applikasjonens deler skje slik:
Vi forenkler det litt hvis vi ikke skal ha alt for kompliserte brukergrensesnitt:
Legg merke til at Viewer
og Model ikke
trenger å vite noen ting om hverandre,
dette er et viktig ideal i OOP; ha så få avhengigheter som
mulig.
Grad2_Loser.as:
package {public class Grad2_Loser {public const INGEN_LOSNINGER: int = 0; public const EN_LOSNING: int = 1; public const TO_LOSNINGER: int = 2; public const KOMPLEKSE_LOSNINGER: int = 3; public const UENDELIG_MANGE_LOSNINGER: int = 4;private var a: Number = 0.0;...private var x1: Number = 0.0;...private var state: int = 0;public function setA(a: Number): void { this.a = a; beregn(); }//setA()...public function getState():int { return state; }//getState();public function getX1(): Number{ return x1; }//getX1()...private function beregn(): void { if(a==0){ if(b==0){ if(c==0){ state = UENDELIG_MANGE_LOSNINGER; }else{ state = INGEN_LOSNINGER; }//if c }else{ state = EN_LOSNING; x1 = -c/b; }//if b }else{ d = b*b - 4*a*c; if(d>0){ state = TO_LOSNINGER; x1 = (-b+Math.sqrt(d))/(2*a); x2 = (-b-Math.sqrt(d))/(2*a); }else if(d==0){ state = EN_LOSNING; x1 = -b/(2*a); }else{ state = KOMPLEKSE_LOSNINGER; r = -b/(2*a); im = Math.sqrt(-d)/(2*a); }//if d }//if a }//beregn() }//class Model }//pacakage
Denne koden kan testes fra Flash, uten å lage grensesnitt, eksempelvis slik:
/* Test av modellen i andregradsprogrammet */const FEILMARGIN: Number = 0.00001;var m: Grad2_Loser = new Grad2_Loser();// x^2 -3x +2=0 skal ha løsning 1 og 2:trace("1,-3,2: 1,2"); m.setABC(1,-3,2); if( m.getState()==m.TO_LOSNINGER && Math.abs(m.getX1()-2)<FEILMARGIN && Math.abs(m.getX2()-1)<FEILMARGIN ) { trace("Ok!"); }else{ trace(" *** Test feilet!!! ***"); }//if
Ingen kode nødvendig, kobles opp fra Controller.
Unngår dermed at addEventListener-funksjoner blir utført i tide og utide ved avspilling av MovieClip.Egenskapene fremgår av figuren:
Kan teste ut Viewer med litt enkel kode, som senere kan fjernes/kommenteres ut.:
/* Kode for å teste grensesnitt: (Uten Controller og Model) Bare skriver ut verdier */btnBeregn.addEventListener(MouseEvent.CLICK,beregnKlikket);function beregnKlikket(evt: MouseEvent):void { var a: Number = Number(txtInputA.text); var b: Number = Number(txtInputB.text); var c: Number = Number(txtInputC.text); taResult.text = "a: " + a +"\n"+ "b: " + b +"\n"+ "c: " + c +"\n"; }//beregnKlikket()
Conroller.as:
package {public class Controller extends MovieClip {private var model: Grad2_Loser = new Grad2_Loser(); //Lager ny data-model public function Controller() { // Konstruktør setter opp applikasjonen: btnBeregn.addEventListener(MouseEvent.CLICK,beregn); //btnBeregn i Viewer }//constructor//Lytterfunksjon: private function beregn(evt:Event): void { model.setA(Number(txtInputA.text)); model.setB(Number(txtInputB.text)); model.setC(Number(txtInputC.text)); var status: int = model.getState(); if(status==model.INGEN_LOSNINGER){ taResult.text="Ingen løsninger!"; }else if(status==model.EN_LOSNING) { taResult.text="En løsning: "+model.getX1(); }else if(status==model.TO_LOSNINGER) { taResult.text="To reelle løsninger:\n"+ model.getX1()+"\n"+ model.getX2(); }else if(status==model.KOMPLEKSE_LOSNINGER) { taResult.text="To komplekse løsninger:\n"+ model.getR() + " + i "+model.getIm()+"\n"+ model.getR() + " - i "+model.getIm(); }else if(status==model.UENDELIG_MANGE_LOSNINGER) { taResult.text="Uendelig mange løsninger."; }else { taResult.text="Skal ikke skje, feil !!!"; }//if status }//beregn() }// Class }//Package