INF1010 - våren 2008 Modell - Utsyn - Kontroll (MVC - Model, View, Control) Stein Gjessing Inst. for informatikk Et bankprogram Vi skal lage et program som håndterer kontoene i en bank. En konto eies av en kunde, og har en saldo. Vi bruker substantivmetoden til å finne forslag til klasser (som vi kan lage objekter fra) class Bank class Konto class Kunde class Saldo For kunde og saldo satser vi i denne enkle versjonen av programmet på å bare bruke h.h.v. en String og en double 3 Et bankprogram Vi skal lage et program som håndterer kontoene i en bank. En konto eies av en kunde, og har en saldo. Programmet skal kommunisere med en bruker i Unix/DOS-vinduet Programmet skal kunne administrere kontoene i banken, og i første omgang 1) Opprette en ny konto 2) Fjerne en konto 3) Sette inn penger på en konto 4) Skrive ut bankens forvaltningskapital class Bank I en bank skal vi kunne legge inn en ny kunde, fjerne en kunde, sette inn penger på en kundes konto og finne forvaltningskapitalen til banken (summen av alle beløpene på alle kontoene) 2 4 1
class Bank navn: konti type: HashMap Bank( ) lagbankkunde (...) fjernbankkunde (...) settinn (...) sumallekonti ( ) class Konto Konto-objekt Konto(String nvn) settinn(double belop) double hentsaldo( ) String henteier( ) class Bank { Bank( ) {... private HashMap konti = new HashMap(); public void lagbankkunde(string navn) {... public void fjernbankkunde (String n) {... public void settinn(string navn, double blp) {... double sumallekonti( ) {... // slutt klasse Bank class Konto { Konto (String nvn) {... public void setinn(double belop) {... public double hentsaldo ( ) {... public String henteier( ) {... // slutt klassen Konto 7 class Konto Når en konto opprettes oppgir vi dens eier, og saldoen settes til null. På en konto skal vi kunne sette inn et beløp, finne navnet på eieren og finne innestående beløp UML klassediagram for Bank (mer i INF1050): Bank Konto 1 * Kan f.eks. gi denne Java datastrukturen: Konto-objekter navn: type: Bank type: HashMap type: Bank HashMap-objekt En Collection 6 8 5
Kjente mønstre for programoppdeling Det er mange kjente og velprøvde måter å dele opp programkode. Slike kjente måter kalles design patterns. Tatt fra The Timeless Way of Building, Christoffer Alexander, Oxford University Press, 1979, ISBN 0195024028 Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such away that you can use this solution a million times over, without doing it the same way twice Et slikt programmeringsmønster har dere lært i INF1000 med kommandoløkka som legger ut en meny og tar kommando fra brukeren. Et av de mest kjente: Modell - Utsyn - Kontroll skal dere lære her (Trygve Reenskaug, Sintef) Modell - Utsyn - Kontroll (MVC) Her: Et svært enkelt system for å vise mekanismen. MVC er fortrukket ved noen hundre linjer kode og oppover. Grunnen til å skille disse funksjonene fra hverandre, er at det gjør det lettere : Å utvikle - Konsentrere seg om en ting ad gangen Å endre - Kode om en ting er samlet ett sted F.eks.: Linjebasert vs. Vindusbasert utskrift 11 Modell Utsyn Kontroll = MVC: Model View Control Modell En ren datastruktur som holder alle data om problemet. Utsyn Egen modul for å presentere modellen for brukeren på ulike måter valgt av brukeren (via kontrollen) Kontroll Egen modul/klasse for å motta ordre fra brukeren og enten endre modellen (legge inn nye data, endre, fjerne data) eller kalle en funksjon i utsynet for å gi et nytt bilde av modellen. Omlag samme oppdeling som i klient/tjener baserte distribuerte systemer Modell database (server) Utsyn klienten på distribuerte PCer Kontroll tjener/server med forretningslogikken Tjener (med forretningslogikk) Klienter MVC løsning for banken vår Det skal da være klasser som håndterer : Utsynet for hele systemet (BankUtsyn) Kontrollen for hele systemet (BankKontroll) Pluss, som vi alt har sette på Klassen Bank med hjelpeklassen Konto Database server 10 12 9
Java datastruktur oversikt BankUtsyn-objekt BankKontrollklassedatastruktur main navn: bnk type: BankKontroll bnk = new BankKontroll(); bnk.ordreløkke(); BankUtsyn-objekt leskommando beomnavnogbelop hentnavn hentbelop beomoghentnavn skrivsum BankKontroll-objekt konti Konto-objekter 13 navn: b BankKontroll-objekt BankKontroll type: Bank lagnykunde lagbankkunde fjernbankkunde fjernbankkunde settinn sumallekonti sumallekonti settinn ordrelokke navn: konti navn: u type: HashMap type: BankUtsyn Konto-objekter HashMap-objekt 15 Programskisse av hele Banksystemet /** Utsyn for Bank*/ class BankUtsyn { /** Kontroll av Banksystemet */ public class BankKontroll { private Bank b; private BankUtsyn u; public BankKontroll( ) { b = new Bank( ); u = new BankUtsyn( ); // end BankUtsyn /** Bank */ class Bank { public static void main (String [] args) { BankKontroll bnk; bnk = new BankKontroll( ); bnk.ordreløkke( ); // end Bank /** Konto */ class Konto { void ordreløkke ( ) { // end BankKontroll // end Konto Fullstendig program - uten kommentarer! (se også fil med fullstendig kommentert program) import java.util.*; import easyio.*; /** Modell: Bank og Konto */ class Konto { private String navn; private double saldo; Konto (String n) { navn = n; saldo =0; public void setinn(double d) { saldo += d; public double hentsaldo ( ) {return saldo; public String henteier( ) { return navn; // slutt klass Konto 16
class Bank{ private HashMap konti = new HashMap(); public void lagbankkunde(string navn) { konti.put(navn, new Konto (navn)); public void fjernbankkunde (String n) { konti.remove(n); public double sumallekonti(){ double sum = 0; Iterator it = konti.values().iterator(); while(it.hasnext()) { Konto s = (Konto) it.next(); sum += s.hentsaldo(); return sum; public void settinn (String n, double belop) { Konto k= (Konto) konti.get(n); k.setinn(belop); // slutt class Bank void ordreløkke () { int valg; valg= u.leskommando(); while(valg!= 0) { switch (valg) { case 1: lagnykunde( ); break; case 2: fjernbankkunde( ); break; case 3: settinn( ); break; case 4: sumallekonti( ); break; default: u.skrivfeil("gi tall mellom 0-4"); valg= u.leskommando( ); // end ordreløkke // end class BankKontroll 17 19 public class BankKontroll { private Bank b; private BankUtsyn u; public BankKontroll( ) {b = new Bank(); u = new BankUtsyn( ); public static void main (String [] args) { BankKontroll bnk = new BankKontroll(); bnk.ordreløkke(); void lagnykunde () { String nvn = u.beomoghentnavn(); b.lagbankkunde(nvn); void fjernbankkunde () { void settinn() { String nvn = u.beomoghentnavn(); b.fjernbankkunde(nvn); u.beomnavnogbelop( ); String navn = u.hentnavn( ); double bel = u.hentbelop( ); b.settinn(navn,bel); public void sumallekonti(){ double sum=0; sum= b.sumallekonti(); u.skrivsum(sum); class BankUtsyn { // Vising av kundedata BankData b; Out ut; In tast; String navn; double belop; // kortvarig oppbevaring av leste data BankUtsyn( ) { tast = new In( ); // In er en klasse i EasyIO ut = new Out( ); // Out er en klasse i EasyIO public int leskommando(){ ut.outln("\nmeny: "); ut.outln("0 - avslutt"); ut.outln("1 - Opprett ny kunde "); ut.outln("2 - Fjern kunde"); ut.outln("3 - Sett inn pange på konto"); ut.outln("4 - Finn forvaltningskapital"); ut.out(" velg funksjon: "); return (tast.inint()); 18 20
public void beomnavnogbelop(){ ut.out("\ngi navn og beløp (på hver sin linje): "); navn = tast.intext(); belop = tast.indouble(); public String hentnavn(){return navn; public double hentbelop(){return belop; public String beomoghentnavn() { ut.out("\ngi navn : "); return tast.intext( ); public void skrivsum(double sum){ ut.outln("\nbankens forvaltningskapital: " + sum) public void skrivfeil(string feil){ ut.outln(feil); // end BankUtsyn Dokumentasjon, brukeropplæring, innføring Ikke del av dette kurset, men meget viktig. Dekkes av kurs fra ISU-gruppa, bl.a. INF1050 Neste gang: sub-klasser VIKTIG! 21 23 Testing (mer i INF1050) Alle klasser og metoder testes først separat, så samlet Regresstesting kjør alle gamle tester + evt. nye hver gang noe endres (ikke bare test det nye med nye tester) Testing kan aldri vise fravær av feil, bare at systemet virker for visse inndata. Bevis av programmer? Særs vanskelig og dyrt Lønner seg bare i helt spesielle tilfeller 22